blob: b7d3f615bc6c7d73386ed5bfe710f52a262ca711 [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 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001415VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001416{
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 */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301486 hdd_context_t *pHddCtx;
1487 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001488
1489 ENTER();
1490
1491 if( NULL == dev )
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
1494 "%s: Called with dev = NULL.\n", __func__);
1495 return -ENODEV;
1496 }
1497 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1498
1499 hddLog(VOS_TRACE_LEVEL_INFO,
1500 "%s: device_mode = %d freq = %d \n",__func__,
1501 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301502
1503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1504 status = wlan_hdd_validate_context(pHddCtx);
1505
1506 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1509 "%s: HDD context is not valid", __func__);
1510 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001511 }
1512
1513 /*
1514 * Do freq to chan conversion
1515 * TODO: for 11a
1516 */
1517
1518 channel = ieee80211_frequency_to_channel(freq);
1519
1520 /* Check freq range */
1521 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1522 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR,
1525 "%s: Channel [%d] is outside valid range from %d to %d\n",
1526 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1527 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1528 return -EINVAL;
1529 }
1530
1531 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1532
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301533 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1534 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001535 {
1536 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: Invalid Channel [%d] \n", __func__, channel);
1540 return -EINVAL;
1541 }
1542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1543 "%s: set channel to [%d] for device mode =%d",
1544 __func__, channel,pAdapter->device_mode);
1545 }
1546 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001547 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001548 )
1549 {
1550 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1551 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1553
1554 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1555 {
1556 /* Link is up then return cant set channel*/
1557 hddLog( VOS_TRACE_LEVEL_ERROR,
1558 "%s: IBSS Associated, can't set the channel\n", __func__);
1559 return -EINVAL;
1560 }
1561
1562 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1563 pHddStaCtx->conn_info.operationChannel = channel;
1564 pRoamProfile->ChannelInfo.ChannelList =
1565 &pHddStaCtx->conn_info.operationChannel;
1566 }
1567 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001568 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001569 )
1570 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301571 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1572 {
1573 if(VOS_STATUS_SUCCESS !=
1574 wlan_hdd_validate_operation_channel(pAdapter,channel))
1575 {
1576 hddLog(VOS_TRACE_LEVEL_ERROR,
1577 "%s: Invalid Channel [%d] \n", __func__, channel);
1578 return -EINVAL;
1579 }
1580 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1581 }
1582 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001583 {
1584 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1585
1586 /* If auto channel selection is configured as enable/ 1 then ignore
1587 channel set by supplicant
1588 */
1589 if ( cfg_param->apAutoChannelSelection )
1590 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301591 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1592 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001593 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1594 "%s: set channel to auto channel (0) for device mode =%d",
1595 __func__, pAdapter->device_mode);
1596 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301597 else
1598 {
1599 if(VOS_STATUS_SUCCESS !=
1600 wlan_hdd_validate_operation_channel(pAdapter,channel))
1601 {
1602 hddLog(VOS_TRACE_LEVEL_ERROR,
1603 "%s: Invalid Channel [%d] \n", __func__, channel);
1604 return -EINVAL;
1605 }
1606 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1607 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001608 }
1609 }
1610 else
1611 {
1612 hddLog(VOS_TRACE_LEVEL_FATAL,
1613 "%s: Invalid device mode failed to set valid channel", __func__);
1614 return -EINVAL;
1615 }
1616 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301617 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001618}
1619
Jeff Johnson295189b2012-06-20 16:38:30 -07001620#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1621static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1622 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001623#else
1624static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1625 struct cfg80211_beacon_data *params,
1626 const u8 *ssid, size_t ssid_len,
1627 enum nl80211_hidden_ssid hidden_ssid)
1628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001629{
1630 tsap_Config_t *pConfig;
1631 beacon_data_t *pBeacon = NULL;
1632 struct ieee80211_mgmt *pMgmt_frame;
1633 v_U8_t *pIe=NULL;
1634 v_U16_t capab_info;
1635 eCsrAuthType RSNAuthType;
1636 eCsrEncryptionType RSNEncryptType;
1637 eCsrEncryptionType mcRSNEncryptType;
1638 int status = VOS_STATUS_SUCCESS;
1639 tpWLAN_SAPEventCB pSapEventCallback;
1640 hdd_hostapd_state_t *pHostapdState;
1641 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1642 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301643 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 struct qc_mac_acl_entry *acl_entry = NULL;
1645 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001646 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001647
1648 ENTER();
1649
1650 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1651
1652 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1653
1654 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1655
1656 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1657
1658 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1659
1660 //channel is already set in the set_channel Call back
1661 //pConfig->channel = pCommitConfig->channel;
1662
1663 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301664 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1666
1667 pConfig->dtim_period = pBeacon->dtim_period;
1668
1669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1670 pConfig->dtim_period);
1671
1672
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001673 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001674 {
1675 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001677 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001679 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001680 pConfig->ieee80211d = 1;
1681 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1682 sme_setRegInfo(hHal, pConfig->countryCode);
1683 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001684 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001685 else
1686 {
1687 pConfig->ieee80211d = 0;
1688 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301689 /*
1690 * If auto channel is configured i.e. channel is 0,
1691 * so skip channel validation.
1692 */
1693 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1694 {
1695 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1696 {
1697 hddLog(VOS_TRACE_LEVEL_ERROR,
1698 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1699 return -EINVAL;
1700 }
1701 }
1702 else
1703 {
1704 if(1 != pHddCtx->is_dynamic_channel_range_set)
1705 {
1706 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1707 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1708 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1709 }
1710 pHddCtx->is_dynamic_channel_range_set = 0;
1711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001712 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001713 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 {
1715 pConfig->ieee80211d = 0;
1716 }
1717 pConfig->authType = eSAP_AUTO_SWITCH;
1718
1719 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301720
1721 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1723
1724 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1725
1726 /*Set wps station to configured*/
1727 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1728
1729 if(pIe)
1730 {
1731 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1732 {
1733 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1734 return -EINVAL;
1735 }
1736 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1737 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001738 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 /* Check 15 bit of WPS IE as it contain information for wps state
1740 * WPS state
1741 */
1742 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1743 {
1744 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1745 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1746 {
1747 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1748 }
1749 }
1750 }
1751 else
1752 {
1753 pConfig->wps_state = SAP_WPS_DISABLED;
1754 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301755 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001756
1757 pConfig->RSNWPAReqIELength = 0;
1758 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301759 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001760 WLAN_EID_RSN);
1761 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301762 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1764 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1765 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301766 /* The actual processing may eventually be more extensive than
1767 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 * by the app.
1769 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301770 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1772 &RSNEncryptType,
1773 &mcRSNEncryptType,
1774 &RSNAuthType,
1775 pConfig->pRSNWPAReqIE[1]+2,
1776 pConfig->pRSNWPAReqIE );
1777
1778 if( VOS_STATUS_SUCCESS == status )
1779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301780 /* Now copy over all the security attributes you have
1781 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 * */
1783 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1784 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1785 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1786 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301787 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 "EncryptionType = %d mcEncryptionType = %d\n"),
1789 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1790 }
1791 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1794 pBeacon->tail, pBeacon->tail_len);
1795
1796 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1797 {
1798 if (pConfig->pRSNWPAReqIE)
1799 {
1800 /*Mixed mode WPA/WPA2*/
1801 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1802 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1803 }
1804 else
1805 {
1806 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1807 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1808 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301809 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1811 &RSNEncryptType,
1812 &mcRSNEncryptType,
1813 &RSNAuthType,
1814 pConfig->pRSNWPAReqIE[1]+2,
1815 pConfig->pRSNWPAReqIE );
1816
1817 if( VOS_STATUS_SUCCESS == status )
1818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301819 /* Now copy over all the security attributes you have
1820 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 * */
1822 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1823 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1824 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1825 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301826 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001827 "EncryptionType = %d mcEncryptionType = %d\n"),
1828 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1829 }
1830 }
1831 }
1832
Jeff Johnson4416a782013-03-25 14:17:50 -07001833 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1834 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1835 return -EINVAL;
1836 }
1837
Jeff Johnson295189b2012-06-20 16:38:30 -07001838 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1839
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001840#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 if (params->ssid != NULL)
1842 {
1843 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1844 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1845 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1846 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1847 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001848#else
1849 if (ssid != NULL)
1850 {
1851 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1852 pConfig->SSIDinfo.ssid.length = ssid_len;
1853 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1854 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1855 }
1856#endif
1857
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301858 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301860
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 /* default value */
1862 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1863 pConfig->num_accept_mac = 0;
1864 pConfig->num_deny_mac = 0;
1865
1866 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1867 pBeacon->tail, pBeacon->tail_len);
1868
1869 /* pIe for black list is following form:
1870 type : 1 byte
1871 length : 1 byte
1872 OUI : 4 bytes
1873 acl type : 1 byte
1874 no of mac addr in black list: 1 byte
1875 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301876 */
1877 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 {
1879 pConfig->SapMacaddr_acl = pIe[6];
1880 pConfig->num_deny_mac = pIe[7];
1881 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1882 pIe[6], pIe[7]);
1883 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1884 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1885 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1886 for (i = 0; i < pConfig->num_deny_mac; i++)
1887 {
1888 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1889 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 }
1892 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1893 pBeacon->tail, pBeacon->tail_len);
1894
1895 /* pIe for white list is following form:
1896 type : 1 byte
1897 length : 1 byte
1898 OUI : 4 bytes
1899 acl type : 1 byte
1900 no of mac addr in white list: 1 byte
1901 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301902 */
1903 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 {
1905 pConfig->SapMacaddr_acl = pIe[6];
1906 pConfig->num_accept_mac = pIe[7];
1907 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1908 pIe[6], pIe[7]);
1909 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1910 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1911 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1912 for (i = 0; i < pConfig->num_accept_mac; i++)
1913 {
1914 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1915 acl_entry++;
1916 }
1917 }
1918 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1919
Jeff Johnsone7245742012-09-05 17:12:55 -07001920#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001921 /* Overwrite the hostapd setting for HW mode only for 11ac.
1922 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1923 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1924 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1925 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301926 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001927 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1928 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001929 {
1930 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1931 }
1932#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301933
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001934 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1935 {
1936 sme_SelectCBMode(hHal,
1937 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1938 pConfig->channel);
1939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 // ht_capab is not what the name conveys,this is used for protection bitmap
1941 pConfig->ht_capab =
1942 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1943
1944 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1945 {
1946 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1947 return -EINVAL;
1948 }
1949
1950 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301951 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1953 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301954 pConfig->obssProtEnabled =
1955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001956
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301957 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301959 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1961 (int)pConfig->channel);
1962 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301963 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1964 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301966 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1968 pConfig->protEnabled, pConfig->obssProtEnabled);
1969
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301970 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 {
1972 //Bss already started. just return.
1973 //TODO Probably it should update some beacon params.
1974 hddLog( LOGE, "Bss Already started...Ignore the request");
1975 EXIT();
1976 return 0;
1977 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 pConfig->persona = pHostapdAdapter->device_mode;
1980
1981 pSapEventCallback = hdd_hostapd_SAPEventCB;
1982 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1983 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1984 {
1985 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1986 return -EINVAL;
1987 }
1988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301989 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1991
1992 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301993
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301995 {
1996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 ("ERROR: HDD vos wait for single_event failed!!\n"));
1998 VOS_ASSERT(0);
1999 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302000
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 //Succesfully started Bss update the state bit.
2002 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2003
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002004#ifdef WLAN_FEATURE_P2P_DEBUG
2005 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2006 {
2007 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2008 {
2009 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2010 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002011 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002012 }
2013 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2014 {
2015 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2016 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002017 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002018 }
2019 }
2020#endif
2021
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 pHostapdState->bCommit = TRUE;
2023 EXIT();
2024
2025 return 0;
2026}
2027
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002028#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2030 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 struct beacon_parameters *params)
2032{
2033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302034 hdd_context_t *pHddCtx;
2035 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002036
2037 ENTER();
2038
2039 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2042 status = wlan_hdd_validate_context(pHddCtx);
2043
2044 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2047 "%s: HDD context is not valid", __func__);
2048 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002049 }
2050
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 )
2054 {
2055 beacon_data_t *old,*new;
2056
2057 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302058
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 if (old)
2060 return -EALREADY;
2061
2062 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2063
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302064 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 {
2066 hddLog(VOS_TRACE_LEVEL_FATAL,
2067 "%s:Error!!! Allocating the new beacon\n",__func__);
2068 return -EINVAL;
2069 }
2070
2071 pAdapter->sessionCtx.ap.beacon = new;
2072
2073 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2074 }
2075
2076 EXIT();
2077 return status;
2078}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302079
2080static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 struct net_device *dev,
2082 struct beacon_parameters *params)
2083{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302085 hdd_context_t *pHddCtx;
2086 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002087
2088 ENTER();
2089
2090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2091 __func__,pAdapter->device_mode);
2092
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2094 status = wlan_hdd_validate_context(pHddCtx);
2095
2096 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2099 "%s: HDD context is not valid", __func__);
2100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002101 }
2102
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302103 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302105 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 {
2107 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302110
Jeff Johnson295189b2012-06-20 16:38:30 -07002111 if (!old)
2112 return -ENOENT;
2113
2114 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2115
2116 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302117 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 "%s: Error!!! Allocating the new beacon\n",__func__);
2119 return -EINVAL;
2120 }
2121
2122 pAdapter->sessionCtx.ap.beacon = new;
2123
2124 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2125 }
2126
2127 EXIT();
2128 return status;
2129}
2130
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002131#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2132
2133#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002134static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2135 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002136#else
2137static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2138 struct net_device *dev)
2139#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002140{
2141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002142 hdd_context_t *pHddCtx = NULL;
2143 hdd_scaninfo_t *pScanInfo = NULL;
2144 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302145 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002146
2147 ENTER();
2148
2149 if (NULL == pAdapter)
2150 {
2151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002152 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 return -ENODEV;
2154 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002155
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302156 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2157 status = wlan_hdd_validate_context(pHddCtx);
2158
2159 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2162 "%s: HDD context is not valid", __func__);
2163 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002164 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002165
2166 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2167 if (NULL == staAdapter)
2168 {
2169 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2170 if (NULL == staAdapter)
2171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002173 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002174 return -ENODEV;
2175 }
2176 }
2177
2178 pScanInfo = &pHddCtx->scan_info;
2179
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2181 __func__,pAdapter->device_mode);
2182
Jeff Johnsone7245742012-09-05 17:12:55 -07002183 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2184 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002185 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002186 hdd_abort_mac_scan(staAdapter->pHddCtx);
2187 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002188 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002189 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2190 if (!status)
2191 {
2192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002193 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002194 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002195 VOS_ASSERT(pScanInfo->mScanPending);
2196 return 0;
2197 }
2198 }
2199
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 )
2203 {
2204 beacon_data_t *old;
2205
2206 old = pAdapter->sessionCtx.ap.beacon;
2207
2208 if (!old)
2209 return -ENOENT;
2210
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002212
2213 mutex_lock(&pHddCtx->sap_lock);
2214 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2215 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002216 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 {
2218 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2219
2220 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2221
2222 if (!VOS_IS_STATUS_SUCCESS(status))
2223 {
2224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 ("ERROR: HDD vos wait for single_event failed!!\n"));
2226 VOS_ASSERT(0);
2227 }
2228 }
2229 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2230 }
2231 mutex_unlock(&pHddCtx->sap_lock);
2232
2233 if(status != VOS_STATUS_SUCCESS)
2234 {
2235 hddLog(VOS_TRACE_LEVEL_FATAL,
2236 "%s:Error!!! Stopping the BSS\n",__func__);
2237 return -EINVAL;
2238 }
2239
Jeff Johnson4416a782013-03-25 14:17:50 -07002240 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2242 ==eHAL_STATUS_FAILURE)
2243 {
2244 hddLog(LOGE,
2245 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2246 }
2247
Jeff Johnson4416a782013-03-25 14:17:50 -07002248 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2250 eANI_BOOLEAN_FALSE) )
2251 {
2252 hddLog(LOGE,
2253 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2254 }
2255
2256 // Reset WNI_CFG_PROBE_RSP Flags
2257 wlan_hdd_reset_prob_rspies(pAdapter);
2258
2259 pAdapter->sessionCtx.ap.beacon = NULL;
2260 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002261#ifdef WLAN_FEATURE_P2P_DEBUG
2262 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2263 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2264 {
2265 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2266 "GO got removed");
2267 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2268 }
2269#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 }
2271 EXIT();
2272 return status;
2273}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002274
2275#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2276
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302277static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2278 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002279 struct cfg80211_ap_settings *params)
2280{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302281 hdd_adapter_t *pAdapter;
2282 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302283 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002284
2285 ENTER();
2286
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302287 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002288 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302290 "%s: Device is Null", __func__);
2291 return -ENODEV;
2292 }
2293
2294 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2295 if (NULL == pAdapter)
2296 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 "%s: HDD adapter is Null", __func__);
2299 return -ENODEV;
2300 }
2301
2302 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2303 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302305 "%s: HDD adapter magic is invalid", __func__);
2306 return -ENODEV;
2307 }
2308
2309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302310 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302311
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302312 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2315 "%s: HDD context is not valid", __func__);
2316 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302317 }
2318
2319 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2320 __func__, pAdapter->device_mode);
2321
2322 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002323 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002324 )
2325 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302326 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327
2328 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302329
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002330 if (old)
2331 return -EALREADY;
2332
2333 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2334
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302335 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002336 {
2337 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302338 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002339 return -EINVAL;
2340 }
2341 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2343 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2344#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2346 params->ssid_len, params->hidden_ssid);
2347 }
2348
2349 EXIT();
2350 return status;
2351}
2352
2353
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302354static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002355 struct net_device *dev,
2356 struct cfg80211_beacon_data *params)
2357{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302359 hdd_context_t *pHddCtx;
2360 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002361
2362 ENTER();
2363
2364 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2365 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302366
2367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2368 status = wlan_hdd_validate_context(pHddCtx);
2369
2370 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002371 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "%s: HDD context is not valid", __func__);
2374 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002375 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002376
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302377 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002378 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302379 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002380 {
2381 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302382
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002383 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302384
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002385 if (!old)
2386 return -ENOENT;
2387
2388 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2389
2390 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302391 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002392 "%s: Error!!! Allocating the new beacon\n",__func__);
2393 return -EINVAL;
2394 }
2395
2396 pAdapter->sessionCtx.ap.beacon = new;
2397
2398 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2399 }
2400
2401 EXIT();
2402 return status;
2403}
2404
2405#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2406
Jeff Johnson295189b2012-06-20 16:38:30 -07002407
2408static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2409 struct net_device *dev,
2410 struct bss_parameters *params)
2411{
2412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2413
2414 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302415
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2417 __func__,pAdapter->device_mode);
2418
2419 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302421 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002422 {
2423 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2424 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302425 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002426 {
2427 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 }
2430
2431 EXIT();
2432 return 0;
2433}
2434
2435/*
2436 * FUNCTION: wlan_hdd_cfg80211_change_iface
2437 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2438 */
2439int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2440 struct net_device *ndev,
2441 enum nl80211_iftype type,
2442 u32 *flags,
2443 struct vif_params *params
2444 )
2445{
2446 struct wireless_dev *wdev;
2447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002449 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002450 tCsrRoamProfile *pRoamProfile = NULL;
2451 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302452 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 eMib_dot11DesiredBssType connectedBssType;
2454 VOS_STATUS status;
2455
2456 ENTER();
2457
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302458 status = wlan_hdd_validate_context(pHddCtx);
2459
2460 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2463 "%s: HDD context is not valid", __func__);
2464 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 }
2466
2467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2468 __func__, pAdapter->device_mode);
2469
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302470 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002471 wdev = ndev->ieee80211_ptr;
2472
2473#ifdef WLAN_BTAMP_FEATURE
2474 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2475 (NL80211_IFTYPE_ADHOC == type)||
2476 (NL80211_IFTYPE_AP == type)||
2477 (NL80211_IFTYPE_P2P_GO == type))
2478 {
2479 pHddCtx->isAmpAllowed = VOS_FALSE;
2480 // stop AMP traffic
2481 status = WLANBAP_StopAmp();
2482 if(VOS_STATUS_SUCCESS != status )
2483 {
2484 pHddCtx->isAmpAllowed = VOS_TRUE;
2485 hddLog(VOS_TRACE_LEVEL_FATAL,
2486 "%s: Failed to stop AMP", __func__);
2487 return -EINVAL;
2488 }
2489 }
2490#endif //WLAN_BTAMP_FEATURE
2491 /* Reset the current device mode bit mask*/
2492 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2493
2494 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002495 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002496 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 )
2498 {
2499 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2500 pRoamProfile = &pWextState->roamProfile;
2501 LastBSSType = pRoamProfile->BSSType;
2502
2503 switch (type)
2504 {
2505 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 hddLog(VOS_TRACE_LEVEL_INFO,
2508 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2509 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002510#ifdef WLAN_FEATURE_11AC
2511 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2512 {
2513 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2514 }
2515#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302516 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002517 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002519 //Check for sub-string p2p to confirm its a p2p interface
2520 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302521 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002522 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2523 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2524 }
2525 else
2526 {
2527 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002528 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 break;
2531 case NL80211_IFTYPE_ADHOC:
2532 hddLog(VOS_TRACE_LEVEL_INFO,
2533 "%s: setting interface Type to ADHOC", __func__);
2534 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2535 pRoamProfile->phyMode =
2536 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002537 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 wdev->iftype = type;
2539 break;
2540
2541 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002543 {
2544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2545 "%s: setting interface Type to %s", __func__,
2546 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2547
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002548 //Cancel any remain on channel for GO mode
2549 if (NL80211_IFTYPE_P2P_GO == type)
2550 {
2551 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2552 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002553 if (NL80211_IFTYPE_AP == type)
2554 {
2555 /* As Loading WLAN Driver one interface being created for p2p device
2556 * address. This will take one HW STA and the max number of clients
2557 * that can connect to softAP will be reduced by one. so while changing
2558 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2559 * interface as it is not required in SoftAP mode.
2560 */
2561
2562 // Get P2P Adapter
2563 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2564
2565 if (pP2pAdapter)
2566 {
2567 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2568 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2569 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2570 }
2571 }
2572
Jeff Johnson295189b2012-06-20 16:38:30 -07002573 //De-init the adapter.
2574 hdd_stop_adapter( pHddCtx, pAdapter );
2575 hdd_deinit_adapter( pHddCtx, pAdapter );
2576 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2578 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002579
2580 //Disable BMPS and IMPS if enabled
2581 //before starting Go
2582 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302584 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002585 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2586 {
2587 //Fail to Exit BMPS
2588 VOS_ASSERT(0);
2589 }
2590 }
2591
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002592 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2593 (pConfig->apRandomBssidEnabled))
2594 {
2595 /* To meet Android requirements create a randomized
2596 MAC address of the form 02:1A:11:Fx:xx:xx */
2597 get_random_bytes(&ndev->dev_addr[3], 3);
2598 ndev->dev_addr[0] = 0x02;
2599 ndev->dev_addr[1] = 0x1A;
2600 ndev->dev_addr[2] = 0x11;
2601 ndev->dev_addr[3] |= 0xF0;
2602 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2603 VOS_MAC_ADDR_SIZE);
2604 pr_info("wlan: Generated HotSpot BSSID "
2605 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2606 ndev->dev_addr[0],
2607 ndev->dev_addr[1],
2608 ndev->dev_addr[2],
2609 ndev->dev_addr[3],
2610 ndev->dev_addr[4],
2611 ndev->dev_addr[5]);
2612 }
2613
Jeff Johnson295189b2012-06-20 16:38:30 -07002614 hdd_set_ap_ops( pAdapter->dev );
2615
2616 status = hdd_init_ap_mode(pAdapter);
2617 if(status != VOS_STATUS_SUCCESS)
2618 {
2619 hddLog(VOS_TRACE_LEVEL_FATAL,
2620 "%s: Error initializing the ap mode", __func__);
2621 return -EINVAL;
2622 }
2623 hdd_set_conparam(1);
2624
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 /*interface type changed update in wiphy structure*/
2626 if(wdev)
2627 {
2628 wdev->iftype = type;
2629 pHddCtx->change_iface = type;
2630 }
2631 else
2632 {
2633 hddLog(VOS_TRACE_LEVEL_ERROR,
2634 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2635 return -EINVAL;
2636 }
2637 goto done;
2638 }
2639
2640 default:
2641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2642 __func__);
2643 return -EOPNOTSUPP;
2644 }
2645 }
2646 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002647 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002648 )
2649 {
2650 switch(type)
2651 {
2652 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002654 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002655 hdd_stop_adapter( pHddCtx, pAdapter );
2656 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002658 //Check for sub-string p2p to confirm its a p2p interface
2659 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002660 {
2661 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2662 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2663 }
2664 else
2665 {
2666 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002667 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 hdd_set_conparam(0);
2670 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2672 hdd_set_station_ops( pAdapter->dev );
2673 status = hdd_init_station_mode( pAdapter );
2674 if( VOS_STATUS_SUCCESS != status )
2675 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002676 /* In case of JB, for P2P-GO, only change interface will be called,
2677 * This is the right place to enable back bmps_imps()
2678 */
2679 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 goto done;
2681 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002684 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2685 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002686 goto done;
2687 default:
2688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2689 __func__);
2690 return -EOPNOTSUPP;
2691
2692 }
2693
2694 }
2695 else
2696 {
2697 return -EOPNOTSUPP;
2698 }
2699
2700
2701 if(pRoamProfile)
2702 {
2703 if ( LastBSSType != pRoamProfile->BSSType )
2704 {
2705 /*interface type changed update in wiphy structure*/
2706 wdev->iftype = type;
2707
2708 /*the BSS mode changed, We need to issue disconnect
2709 if connected or in IBSS disconnect state*/
2710 if ( hdd_connGetConnectedBssType(
2711 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2712 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2713 {
2714 /*need to issue a disconnect to CSR.*/
2715 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2716 if( eHAL_STATUS_SUCCESS ==
2717 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2718 pAdapter->sessionId,
2719 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2720 {
2721 wait_for_completion_interruptible_timeout(
2722 &pAdapter->disconnect_comp_var,
2723 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2724 }
2725 }
2726 }
2727 }
2728
2729done:
2730 /*set bitmask based on updated value*/
2731 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2732#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302733 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002734 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2735 {
2736 //we are ok to do AMP
2737 pHddCtx->isAmpAllowed = VOS_TRUE;
2738 }
2739#endif //WLAN_BTAMP_FEATURE
2740 EXIT();
2741 return 0;
2742}
2743
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002744#ifdef FEATURE_WLAN_TDLS
2745static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2746 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2747{
2748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2749 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2750 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002751 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002752
2753 ENTER();
2754
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302755 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002756 {
2757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2758 "Invalid arguments");
2759 return -EINVAL;
2760 }
Hoonki Lee27511902013-03-14 18:19:06 -07002761
2762 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2763 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2764 {
2765 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2766 "%s: TDLS mode is disabled OR not enabled in FW."
2767 MAC_ADDRESS_STR " Request declined.",
2768 __func__, MAC_ADDR_ARRAY(mac));
2769 return -ENOTSUPP;
2770 }
2771
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002772 if (pHddCtx->isLogpInProgress)
2773 {
2774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2775 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002776 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002777 return -EBUSY;
2778 }
2779
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002780 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2781
2782 if ( NULL == pTdlsPeer ) {
2783 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2784 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2785 __func__, MAC_ADDR_ARRAY(mac), update);
2786 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002787 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002788
2789 /* in add station, we accept existing valid staId if there is */
2790 if ((0 == update) &&
2791 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2792 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002793 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002794 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002795 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002796 " link_status %d. staId %d. add station ignored.",
2797 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2798 return 0;
2799 }
2800 /* in change station, we accept only when staId is valid */
2801 if ((1 == update) &&
2802 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2803 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2804 {
2805 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2806 "%s: " MAC_ADDRESS_STR
2807 " link status %d. staId %d. change station %s.",
2808 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2809 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2810 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002811 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002812
2813 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002814 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2817 "%s: " MAC_ADDRESS_STR
2818 " TDLS setup is ongoing. Request declined.",
2819 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002820 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002821 }
2822
2823 /* first to check if we reached to maximum supported TDLS peer.
2824 TODO: for now, return -EPERM looks working fine,
2825 but need to check if any other errno fit into this category.*/
2826 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2827 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: " MAC_ADDRESS_STR
2830 " TDLS Max peer already connected. Request declined.",
2831 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002832 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002833 }
2834 else
2835 {
2836 hddTdlsPeer_t *pTdlsPeer;
2837 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002838 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002839 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2841 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2842 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002843 return -EPERM;
2844 }
2845 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002846 if (0 == update)
2847 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848
Jeff Johnsond75fe012013-04-06 10:53:06 -07002849 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302850 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002851 {
2852 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2853 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002854 if(StaParams->htcap_present)
2855 {
2856 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2857 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2858 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2859 "ht_capa->extended_capabilities: %0x",
2860 StaParams->HTCap.extendedHtCapInfo);
2861 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002862 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2863 "params->capability: %0x",StaParams->capability);
2864 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2865 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002866 if(StaParams->vhtcap_present)
2867 {
2868 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2869 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2870 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2871 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2872 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002873 {
2874 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002876 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2877 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2878 "[%d]: %x ", i, StaParams->supported_rates[i]);
2879 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002880 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302881 else if ((1 == update) && (NULL == StaParams))
2882 {
2883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2884 "%s : update is true, but staParams is NULL. Error!", __func__);
2885 return -EPERM;
2886 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002887
2888 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2889
2890 if (!update)
2891 {
2892 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2893 pAdapter->sessionId, mac);
2894 }
2895 else
2896 {
2897 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2898 pAdapter->sessionId, mac, StaParams);
2899 }
2900
2901 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2902 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2903
2904 if (!status)
2905 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002907 "%s: timeout waiting for tdls add station indication",
2908 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002909 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002910 }
2911 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2912 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002914 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002915 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002916 }
2917
2918 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002919
2920error:
2921 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2922 return -EPERM;
2923
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002924}
2925#endif
2926
Jeff Johnson295189b2012-06-20 16:38:30 -07002927static int wlan_hdd_change_station(struct wiphy *wiphy,
2928 struct net_device *dev,
2929 u8 *mac,
2930 struct station_parameters *params)
2931{
2932 VOS_STATUS status = VOS_STATUS_SUCCESS;
2933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302934 hdd_context_t *pHddCtx;
2935 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002937#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002938 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002939 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002940#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002941 ENTER();
2942
Gopichand Nakkala29149562013-05-10 21:43:41 +05302943 if ((NULL == pAdapter))
2944 {
2945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2946 "invalid adapter ");
2947 return -EINVAL;
2948 }
2949
2950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2951 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2952
2953 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2954 {
2955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2956 "invalid HDD state or HDD station context");
2957 return -EINVAL;
2958 }
2959
2960 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002961 {
2962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2963 "%s:LOGP in Progress. Ignore!!!", __func__);
2964 return -EAGAIN;
2965 }
2966
Jeff Johnson295189b2012-06-20 16:38:30 -07002967 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2968
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002969 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2970 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002971 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002972 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302974 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 WLANTL_STA_AUTHENTICATED);
2976
Gopichand Nakkala29149562013-05-10 21:43:41 +05302977 if (status != VOS_STATUS_SUCCESS)
2978 {
2979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2980 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2981 return -EINVAL;
2982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 }
2984 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002985 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2986 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302987#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002988 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2989 StaParams.capability = params->capability;
2990 StaParams.uapsd_queues = params->uapsd_queues;
2991 StaParams.max_sp = params->max_sp;
2992
2993 if (0 != params->ext_capab_len)
2994 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2995 sizeof(StaParams.extn_capability));
2996
2997 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002998 {
2999 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003000 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003001 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003002
3003 StaParams.supported_rates_len = params->supported_rates_len;
3004
3005 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3006 * The supported_rates array , for all the structures propogating till Add Sta
3007 * to the firmware has to be modified , if the supplicant (ieee80211) is
3008 * modified to send more rates.
3009 */
3010
3011 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3012 */
3013 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3014 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3015
3016 if (0 != StaParams.supported_rates_len) {
3017 int i = 0;
3018 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3019 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003021 "Supported Rates with Length %d", StaParams.supported_rates_len);
3022 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003024 "[%d]: %0x", i, StaParams.supported_rates[i]);
3025 }
3026
3027 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003028 {
3029 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003030 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003031 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003032
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003033 if (0 != params->ext_capab_len ) {
3034 /*Define A Macro : TODO Sunil*/
3035 if ((1<<4) & StaParams.extn_capability[3]) {
3036 isBufSta = 1;
3037 }
3038 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003039 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3040 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003041 //if (VOS_STATUS_SUCCESS != status) {
3042 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3043 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3044 // return -EINVAL;
3045 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003046 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3047
3048 if (VOS_STATUS_SUCCESS != status) {
3049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3050 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3051 return -EINVAL;
3052 }
3053 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003054#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303055 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3056 {
3057 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3058 WLANTL_STA_AUTHENTICATED);
3059 if (status != VOS_STATUS_SUCCESS)
3060 {
3061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3062 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3063 return -EINVAL;
3064 }
3065 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3067 "%s: TL Moving to Authenticated state", __func__);
3068 }
3069 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303070
Jeff Johnsone7245742012-09-05 17:12:55 -07003071 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 return status;
3073}
3074
3075/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 * FUNCTION: wlan_hdd_cfg80211_add_key
3077 * This function is used to initialize the key information
3078 */
3079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003080static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003081 struct net_device *ndev,
3082 u8 key_index, bool pairwise,
3083 const u8 *mac_addr,
3084 struct key_params *params
3085 )
3086#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003087static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 struct net_device *ndev,
3089 u8 key_index, const u8 *mac_addr,
3090 struct key_params *params
3091 )
3092#endif
3093{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 tCsrRoamSetKey setKey;
3096 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303097 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003098 v_U32_t roamId= 0xFF;
3099 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 hdd_hostapd_state_t *pHostapdState;
3101 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003102 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303103 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 ENTER();
3106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3108 status = wlan_hdd_validate_context(pHddCtx);
3109
3110 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: HDD context is not valid", __func__);
3114 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003115 }
3116
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3118 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 if (CSR_MAX_NUM_KEY <= key_index)
3121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 key_index);
3124
3125 return -EINVAL;
3126 }
3127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003128 if (CSR_MAX_KEY_LEN < params->key_len)
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3131 params->key_len);
3132
3133 return -EINVAL;
3134 }
3135
3136 hddLog(VOS_TRACE_LEVEL_INFO,
3137 "%s: called with key index = %d & key length %d",
3138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003139
3140 /*extract key idx, key len and key*/
3141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3142 setKey.keyId = key_index;
3143 setKey.keyLength = params->key_len;
3144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 {
3148 case WLAN_CIPHER_SUITE_WEP40:
3149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3150 break;
3151
3152 case WLAN_CIPHER_SUITE_WEP104:
3153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3154 break;
3155
3156 case WLAN_CIPHER_SUITE_TKIP:
3157 {
3158 u8 *pKey = &setKey.Key[0];
3159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3160
3161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003164
3165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 |--------------|----------|----------|
3168 <---16bytes---><--8bytes--><--8bytes-->
3169
3170 */
3171 /*Sme expects the 32 bytes key to be in the below order
3172
3173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 |--------------|----------|----------|
3176 <---16bytes---><--8bytes--><--8bytes-->
3177 */
3178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180
3181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187
3188 break;
3189 }
3190
3191 case WLAN_CIPHER_SUITE_CCMP:
3192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3193 break;
3194
3195#ifdef FEATURE_WLAN_WAPI
3196 case WLAN_CIPHER_SUITE_SMS4:
3197 {
3198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3200 params->key, params->key_len);
3201 return 0;
3202 }
3203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205#ifdef FEATURE_WLAN_CCX
3206 case WLAN_CIPHER_SUITE_KRK:
3207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3208 break;
3209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003210
3211#ifdef WLAN_FEATURE_11W
3212 case WLAN_CIPHER_SUITE_AES_CMAC:
3213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003215#endif
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 default:
3218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3219 __func__, params->cipher);
3220 return -EOPNOTSUPP;
3221 }
3222
3223 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3224 __func__, setKey.encType);
3225
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003226 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3228 (!pairwise)
3229#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003230 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003231#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003232 )
3233 {
3234 /* set group key*/
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s- %d: setting Broadcast key",
3237 __func__, __LINE__);
3238 setKey.keyDirection = eSIR_RX_ONLY;
3239 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3240 }
3241 else
3242 {
3243 /* set pairwise key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s- %d: setting pairwise key",
3246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_TX_RX;
3248 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3249 }
3250 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3251 {
3252 setKey.keyDirection = eSIR_TX_RX;
3253 /*Set the group key*/
3254 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3255 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003256
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003257 if ( 0 != status )
3258 {
3259 hddLog(VOS_TRACE_LEVEL_ERROR,
3260 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3261 return -EINVAL;
3262 }
3263 /*Save the keys here and call sme_RoamSetKey for setting
3264 the PTK after peer joins the IBSS network*/
3265 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3266 &setKey, sizeof(tCsrRoamSetKey));
3267 return status;
3268 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303269 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3270 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3271 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003272 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003273 if( pHostapdState->bssState == BSS_START )
3274 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3276
3277 if ( status != eHAL_STATUS_SUCCESS )
3278 {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3280 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3281 __LINE__, status );
3282 }
3283 }
3284
3285 /* Saving WEP keys */
3286 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3287 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3288 {
3289 //Save the wep key in ap context. Issue setkey after the BSS is started.
3290 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3291 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3292 }
3293 else
3294 {
3295 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003296 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3298 }
3299 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003300 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3301 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003302 {
3303 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3304 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3305
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3307 if (!pairwise)
3308#else
3309 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3310#endif
3311 {
3312 /* set group key*/
3313 if (pHddStaCtx->roam_info.deferKeyComplete)
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3316 "%s- %d: Perform Set key Complete",
3317 __func__, __LINE__);
3318 hdd_PerformRoamSetKeyComplete(pAdapter);
3319 }
3320 }
3321
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3323
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003324 pWextState->roamProfile.Keys.defaultIndex = key_index;
3325
3326
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003327 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003328 params->key, params->key_len);
3329
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303330
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3332
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303333 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303335 __func__, setKey.peerMac[0], setKey.peerMac[1],
3336 setKey.peerMac[2], setKey.peerMac[3],
3337 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003338 setKey.keyDirection);
3339
3340 vos_status = wlan_hdd_check_ula_done(pAdapter);
3341
3342 if ( vos_status != VOS_STATUS_SUCCESS )
3343 {
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3345 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3346 __LINE__, vos_status );
3347
3348 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3349
3350 return -EINVAL;
3351
3352 }
3353
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003354#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303355 /* The supplicant may attempt to set the PTK once pre-authentication
3356 is done. Save the key in the UMAC and include it in the ADD BSS
3357 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003358 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303359 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003360 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303361 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3362 "%s: Update PreAuth Key success", __func__);
3363 return 0;
3364 }
3365 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR,
3368 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303369 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003370 }
3371#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003372
3373 /* issue set key request to SME*/
3374 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3375 pAdapter->sessionId, &setKey, &roamId );
3376
3377 if ( 0 != status )
3378 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303379 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3381 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3382 return -EINVAL;
3383 }
3384
3385
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303386 /* in case of IBSS as there was no information available about WEP keys during
3387 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3390 !( ( IW_AUTH_KEY_MGMT_802_1X
3391 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003392 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3393 )
3394 &&
3395 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3396 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3397 )
3398 )
3399 {
3400 setKey.keyDirection = eSIR_RX_ONLY;
3401 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303403 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003404 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303405 __func__, setKey.peerMac[0], setKey.peerMac[1],
3406 setKey.peerMac[2], setKey.peerMac[3],
3407 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 setKey.keyDirection);
3409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303410 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 pAdapter->sessionId, &setKey, &roamId );
3412
3413 if ( 0 != status )
3414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 __func__, status);
3418 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3419 return -EINVAL;
3420 }
3421 }
3422 }
3423
3424 return 0;
3425}
3426
3427/*
3428 * FUNCTION: wlan_hdd_cfg80211_get_key
3429 * This function is used to get the key information
3430 */
3431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303432static int wlan_hdd_cfg80211_get_key(
3433 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303435 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003436 const u8 *mac_addr, void *cookie,
3437 void (*callback)(void *cookie, struct key_params*)
3438 )
3439#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303440static int wlan_hdd_cfg80211_get_key(
3441 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003442 struct net_device *ndev,
3443 u8 key_index, const u8 *mac_addr, void *cookie,
3444 void (*callback)(void *cookie, struct key_params*)
3445 )
3446#endif
3447{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3450 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3451 struct key_params params;
3452
3453 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303454
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3456 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 memset(&params, 0, sizeof(params));
3459
3460 if (CSR_MAX_NUM_KEY <= key_index)
3461 {
3462 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003464
3465 switch(pRoamProfile->EncryptionType.encryptionType[0])
3466 {
3467 case eCSR_ENCRYPT_TYPE_NONE:
3468 params.cipher = IW_AUTH_CIPHER_NONE;
3469 break;
3470
3471 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3472 case eCSR_ENCRYPT_TYPE_WEP40:
3473 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3474 break;
3475
3476 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3477 case eCSR_ENCRYPT_TYPE_WEP104:
3478 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3479 break;
3480
3481 case eCSR_ENCRYPT_TYPE_TKIP:
3482 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3483 break;
3484
3485 case eCSR_ENCRYPT_TYPE_AES:
3486 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3487 break;
3488
3489 default:
3490 params.cipher = IW_AUTH_CIPHER_NONE;
3491 break;
3492 }
3493
3494 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3495 params.seq_len = 0;
3496 params.seq = NULL;
3497 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3498 callback(cookie, &params);
3499 return 0;
3500}
3501
3502/*
3503 * FUNCTION: wlan_hdd_cfg80211_del_key
3504 * This function is used to delete the key information
3505 */
3506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303507static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303509 u8 key_index,
3510 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 const u8 *mac_addr
3512 )
3513#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303514static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 struct net_device *ndev,
3516 u8 key_index,
3517 const u8 *mac_addr
3518 )
3519#endif
3520{
3521 int status = 0;
3522
3523 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 //it is observed that this is invalidating peer
3526 //key index whenever re-key is done. This is affecting data link.
3527 //It should be ok to ignore del_key.
3528#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3530 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003531 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3532 tCsrRoamSetKey setKey;
3533 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303534
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 ENTER();
3536
3537 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3538 __func__,pAdapter->device_mode);
3539
3540 if (CSR_MAX_NUM_KEY <= key_index)
3541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 key_index);
3544
3545 return -EINVAL;
3546 }
3547
3548 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3549 setKey.keyId = key_index;
3550
3551 if (mac_addr)
3552 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3553 else
3554 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3555
3556 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3557
3558 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003559 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560 )
3561 {
3562
3563 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003564 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3565 if( pHostapdState->bssState == BSS_START)
3566 {
3567 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303568
Jeff Johnson295189b2012-06-20 16:38:30 -07003569 if ( status != eHAL_STATUS_SUCCESS )
3570 {
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3573 __LINE__, status );
3574 }
3575 }
3576 }
3577 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303578 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 )
3580 {
3581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303583 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3584
3585 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303587 __func__, setKey.peerMac[0], setKey.peerMac[1],
3588 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303590 if(pAdapter->sessionCtx.station.conn_info.connState ==
3591 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303593 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 if ( 0 != status )
3597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 "%s: sme_RoamSetKey failure, returned %d",
3600 __func__, status);
3601 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3602 return -EINVAL;
3603 }
3604 }
3605 }
3606#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003607 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 return status;
3609}
3610
3611/*
3612 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3613 * This function is used to set the default tx key index
3614 */
3615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3616static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3617 struct net_device *ndev,
3618 u8 key_index,
3619 bool unicast, bool multicast)
3620#else
3621static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3622 struct net_device *ndev,
3623 u8 key_index)
3624#endif
3625{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303627 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303628 hdd_wext_state_t *pWextState;
3629 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303630 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003631
3632 ENTER();
3633
Gopichand Nakkala29149562013-05-10 21:43:41 +05303634 if ((NULL == pAdapter))
3635 {
3636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3637 "invalid adapter");
3638 return -EINVAL;
3639 }
3640
3641 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3642 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3643
3644 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3645 {
3646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3647 "invalid Wext state or HDD context");
3648 return -EINVAL;
3649 }
3650
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3652 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303653
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 if (CSR_MAX_NUM_KEY <= key_index)
3655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 key_index);
3658
3659 return -EINVAL;
3660 }
3661
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3663 status = wlan_hdd_validate_context(pHddCtx);
3664
3665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3668 "%s: HDD context is not valid", __func__);
3669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303671
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003673 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303674 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303676 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003679 pWextState->roamProfile.EncryptionType.encryptionType[0])
3680 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303681 {
3682 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303684
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 tCsrRoamSetKey setKey;
3686 v_U32_t roamId= 0xFF;
3687 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688
3689 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 Keys->defaultIndex = (u8)key_index;
3693 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3694 setKey.keyId = key_index;
3695 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696
3697 vos_mem_copy(&setKey.Key[0],
3698 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303700
Gopichand Nakkala29149562013-05-10 21:43:41 +05303701 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303702
3703 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 &pHddStaCtx->conn_info.bssId[0],
3705 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706
Gopichand Nakkala29149562013-05-10 21:43:41 +05303707 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3708 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3709 eCSR_ENCRYPT_TYPE_WEP104)
3710 {
3711 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3712 even though ap is configured for WEP-40 encryption. In this canse the key length
3713 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3714 type(104) and switching encryption type to 40*/
3715 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3716 eCSR_ENCRYPT_TYPE_WEP40;
3717 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3718 eCSR_ENCRYPT_TYPE_WEP40;
3719 }
3720
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303725 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303727
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 if ( 0 != status )
3729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003732 status);
3733 return -EINVAL;
3734 }
3735 }
3736 }
3737
3738 /* In SoftAp mode setting key direction for default mode */
3739 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3740 {
3741 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3742 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3743 (eCSR_ENCRYPT_TYPE_AES !=
3744 pWextState->roamProfile.EncryptionType.encryptionType[0])
3745 )
3746 {
3747 /* Saving key direction for default key index to TX default */
3748 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3749 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3750 }
3751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303752
Jeff Johnson295189b2012-06-20 16:38:30 -07003753 return status;
3754}
3755
Jeff Johnson295189b2012-06-20 16:38:30 -07003756/*
3757 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3758 * This function is used to inform the BSS details to nl80211 interface.
3759 */
3760static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3761 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3762{
3763 struct net_device *dev = pAdapter->dev;
3764 struct wireless_dev *wdev = dev->ieee80211_ptr;
3765 struct wiphy *wiphy = wdev->wiphy;
3766 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3767 int chan_no;
3768 int ie_length;
3769 const char *ie;
3770 unsigned int freq;
3771 struct ieee80211_channel *chan;
3772 int rssi = 0;
3773 struct cfg80211_bss *bss = NULL;
3774
3775 ENTER();
3776
3777 if( NULL == pBssDesc )
3778 {
3779 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3780 return bss;
3781 }
3782
3783 chan_no = pBssDesc->channelId;
3784 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3785 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3786
3787 if( NULL == ie )
3788 {
3789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3790 return bss;
3791 }
3792
3793#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3794 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3795 {
3796 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3797 }
3798 else
3799 {
3800 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3801 }
3802#else
3803 freq = ieee80211_channel_to_frequency(chan_no);
3804#endif
3805
3806 chan = __ieee80211_get_channel(wiphy, freq);
3807
3808 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3809 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3810 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3811 if (bss == NULL)
3812 {
3813 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3814
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303815 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3816 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003817 pBssDesc->capabilityInfo,
3818 pBssDesc->beaconInterval, ie, ie_length,
3819 rssi, GFP_KERNEL ));
3820}
3821 else
3822 {
3823 return bss;
3824 }
3825}
3826
3827
3828
3829/*
3830 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3831 * This function is used to inform the BSS details to nl80211 interface.
3832 */
3833struct cfg80211_bss*
3834wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3835 tSirBssDescription *bss_desc
3836 )
3837{
3838 /*
3839 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3840 already exists in bss data base of cfg80211 for that particular BSS ID.
3841 Using cfg80211_inform_bss_frame to update the bss entry instead of
3842 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3843 now there is no possibility to get the mgmt(probe response) frame from PE,
3844 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3845 cfg80211_inform_bss_frame.
3846 */
3847 struct net_device *dev = pAdapter->dev;
3848 struct wireless_dev *wdev = dev->ieee80211_ptr;
3849 struct wiphy *wiphy = wdev->wiphy;
3850 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003851#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3852 qcom_ie_age *qie_age = NULL;
3853 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3854#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 const char *ie =
3858 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3859 unsigned int freq;
3860 struct ieee80211_channel *chan;
3861 struct ieee80211_mgmt *mgmt =
3862 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3863 struct cfg80211_bss *bss_status = NULL;
3864 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3865 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003866#ifdef WLAN_OPEN_SOURCE
3867 struct timespec ts;
3868#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003869
3870 ENTER();
3871
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003872 if (!mgmt)
3873 return NULL;
3874
Jeff Johnson295189b2012-06-20 16:38:30 -07003875 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003876
3877#ifdef WLAN_OPEN_SOURCE
3878 /* Android does not want the timestamp from the frame.
3879 Instead it wants a monotonic increasing value */
3880 get_monotonic_boottime(&ts);
3881 mgmt->u.probe_resp.timestamp =
3882 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3883#else
3884 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3886 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003887
3888#endif
3889
Jeff Johnson295189b2012-06-20 16:38:30 -07003890 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3891 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003892
3893#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3894 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3895 /* Assuming this is the last IE, copy at the end */
3896 ie_length -=sizeof(qcom_ie_age);
3897 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3898 qie_age->element_id = QCOM_VENDOR_IE_ID;
3899 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3900 qie_age->oui_1 = QCOM_OUI1;
3901 qie_age->oui_2 = QCOM_OUI2;
3902 qie_age->oui_3 = QCOM_OUI3;
3903 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3904 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3905#endif
3906
Jeff Johnson295189b2012-06-20 16:38:30 -07003907 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303908 if (bss_desc->fProbeRsp)
3909 {
3910 mgmt->frame_control |=
3911 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3912 }
3913 else
3914 {
3915 mgmt->frame_control |=
3916 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003918
3919#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3922 {
3923 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303925 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003926 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3927
3928 {
3929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3930 }
3931 else
3932 {
3933 kfree(mgmt);
3934 return NULL;
3935 }
3936#else
3937 freq = ieee80211_channel_to_frequency(chan_no);
3938#endif
3939 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003940 /*when the band is changed on the fly using the GUI, three things are done
3941 * 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)
3942 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3943 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3944 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3945 * and discards the channels correponding to previous band and calls back with zero bss results.
3946 * 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
3947 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3948 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3949 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3950 * So drop the bss and continue to next bss.
3951 */
3952 if(chan == NULL)
3953 {
3954 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003955 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003956 return NULL;
3957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303959 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 * */
3961 if (( eConnectionState_Associated ==
3962 pAdapter->sessionCtx.station.conn_info.connState ) &&
3963 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3964 pAdapter->sessionCtx.station.conn_info.bssId,
3965 WNI_CFG_BSSID_LEN)))
3966 {
3967 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3968 rssi = (pAdapter->rssi * 100);
3969 }
3970 else
3971 {
3972 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3973 }
3974
3975 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3976 frame_len, rssi, GFP_KERNEL);
3977 kfree(mgmt);
3978 return bss_status;
3979}
3980
3981/*
3982 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3983 * This function is used to update the BSS data base of CFG8011
3984 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303985struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 tCsrRoamInfo *pRoamInfo
3987 )
3988{
3989 tCsrRoamConnectedProfile roamProfile;
3990 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3991 struct cfg80211_bss *bss = NULL;
3992
3993 ENTER();
3994
3995 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3996 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3997
3998 if (NULL != roamProfile.pBssDesc)
3999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304000 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 &roamProfile);
4002
4003 if (NULL == bss)
4004 {
4005 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4006 __func__);
4007 }
4008
4009 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4010 }
4011 else
4012 {
4013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4014 __func__);
4015 }
4016 return bss;
4017}
4018
4019/*
4020 * FUNCTION: wlan_hdd_cfg80211_update_bss
4021 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304022static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4023 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304025{
Jeff Johnson295189b2012-06-20 16:38:30 -07004026 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4027 tCsrScanResultInfo *pScanResult;
4028 eHalStatus status = 0;
4029 tScanResultHandle pResult;
4030 struct cfg80211_bss *bss_status = NULL;
4031
4032 ENTER();
4033
4034 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4035 {
4036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4037 return -EAGAIN;
4038 }
4039
4040 /*
4041 * start getting scan results and populate cgf80211 BSS database
4042 */
4043 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4044
4045 /* no scan results */
4046 if (NULL == pResult)
4047 {
4048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4049 return status;
4050 }
4051
4052 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4053
4054 while (pScanResult)
4055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 /*
4057 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4058 * entry already exists in bss data base of cfg80211 for that
4059 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4060 * bss entry instead of cfg80211_inform_bss, But this call expects
4061 * mgmt packet as input. As of now there is no possibility to get
4062 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 * ieee80211_mgmt(probe response) and passing to c
4064 * fg80211_inform_bss_frame.
4065 * */
4066
4067 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4068 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304069
Jeff Johnson295189b2012-06-20 16:38:30 -07004070
4071 if (NULL == bss_status)
4072 {
4073 hddLog(VOS_TRACE_LEVEL_INFO,
4074 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4075 }
4076 else
4077 {
4078 cfg80211_put_bss(bss_status);
4079 }
4080
4081 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4082 }
4083
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304084 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004085
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304086 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004087}
4088
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004089void
4090hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4091{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004093 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4094 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4095 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004096} /****** end hddPrintMacAddr() ******/
4097
4098void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004099hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304101 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004102 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4103 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4104 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4105 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004106} /****** end hddPrintPmkId() ******/
4107
4108//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4109//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4110
4111//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4112//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4113
4114#define dump_bssid(bssid) \
4115 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004116 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4117 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4118 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004119 }
4120
4121#define dump_pmkid(pMac, pmkid) \
4122 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004123 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4124 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4125 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004126 }
4127
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004128#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004129/*
4130 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4131 * This function is used to notify the supplicant of a new PMKSA candidate.
4132 */
4133int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004135 int index, bool preauth )
4136{
Jeff Johnsone7245742012-09-05 17:12:55 -07004137#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004139 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004140
4141 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004142 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143
4144 if( NULL == pRoamInfo )
4145 {
4146 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4147 return -EINVAL;
4148 }
4149
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4151 {
4152 dump_bssid(pRoamInfo->bssid);
4153 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004154 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004155 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004156#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004158}
4159#endif //FEATURE_WLAN_LFR
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161/*
4162 * FUNCTION: hdd_cfg80211_scan_done_callback
4163 * scanning callback function, called after finishing scan
4164 *
4165 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4168{
4169 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304170 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004172 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4173 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 struct cfg80211_scan_request *req = NULL;
4175 int ret = 0;
4176
4177 ENTER();
4178
4179 hddLog(VOS_TRACE_LEVEL_INFO,
4180 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 __func__, halHandle, pContext, (int) scanId, (int) status);
4183
4184 //Block on scan req completion variable. Can't wait forever though.
4185 ret = wait_for_completion_interruptible_timeout(
4186 &pScanInfo->scan_req_completion_event,
4187 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4188 if (!ret)
4189 {
4190 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004191 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 }
4193
4194 if(pScanInfo->mScanPending != VOS_TRUE)
4195 {
4196 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004197 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 }
4199
4200 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304201 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 {
4203 hddLog(VOS_TRACE_LEVEL_INFO,
4204 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304205 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 (int) scanId);
4207 }
4208
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304209 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 pAdapter);
4211
4212 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004214
4215
4216 /* If any client wait scan result through WEXT
4217 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004218 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 /* The other scan request waiting for current scan finish
4221 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004222 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004224 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 }
4226 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004227 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 {
4229 struct net_device *dev = pAdapter->dev;
4230 union iwreq_data wrqu;
4231 int we_event;
4232 char *msg;
4233
4234 memset(&wrqu, '\0', sizeof(wrqu));
4235 we_event = SIOCGIWSCAN;
4236 msg = NULL;
4237 wireless_send_event(dev, we_event, &wrqu, msg);
4238 }
4239 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004240 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004241
4242 /* Get the Scan Req */
4243 req = pAdapter->request;
4244
4245 if (!req)
4246 {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004248 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004249 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 }
4251
4252 /*
4253 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304254 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004255 req->n_ssids = 0;
4256 req->n_channels = 0;
4257 req->ie = 0;
4258
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004260 /* Scan is no longer pending */
4261 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004262
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004263 /*
4264 * cfg80211_scan_done informing NL80211 about completion
4265 * of scanning
4266 */
4267 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004268 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Jeff Johnsone7245742012-09-05 17:12:55 -07004270allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004271 /* release the wake lock at the end of the scan*/
4272 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004273
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004274 /* Acquire wakelock to handle the case where APP's tries to suspend
4275 * immediatly after the driver gets connect request(i.e after scan)
4276 * from supplicant, this result in app's is suspending and not able
4277 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004278 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004279
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004280#ifdef FEATURE_WLAN_TDLS
4281 wlan_hdd_tdls_scan_done_callback(pAdapter);
4282#endif
4283
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 EXIT();
4285 return 0;
4286}
4287
4288/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004289 * FUNCTION: hdd_isScanAllowed
4290 * Go through each adapter and check if scan allowed
4291 *
4292 */
4293v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4294{
4295 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4296 hdd_station_ctx_t *pHddStaCtx = NULL;
4297 hdd_adapter_t *pAdapter = NULL;
4298 VOS_STATUS status = 0;
4299 v_U8_t staId = 0;
4300 v_U8_t *staMac = NULL;
4301
4302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4303
4304 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4305 {
4306 pAdapter = pAdapterNode->pAdapter;
4307
4308 if( pAdapter )
4309 {
4310 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304311 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004312 __func__, pAdapter->device_mode);
4313 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4314 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4315 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4316 {
4317 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4318 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4319 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4320 {
4321 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304324 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004325 staMac[0], staMac[1], staMac[2],
4326 staMac[3], staMac[4], staMac[5]);
4327 return VOS_FALSE;
4328 }
4329 }
4330 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4331 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4332 {
4333 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004336 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4337 {
4338 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4339
4340 hddLog(VOS_TRACE_LEVEL_ERROR,
4341 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004343 staMac[0], staMac[1], staMac[2],
4344 staMac[3], staMac[4], staMac[5]);
4345 return VOS_FALSE;
4346 }
4347 }
4348 }
4349 }
4350 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4351 pAdapterNode = pNext;
4352 }
4353 hddLog(VOS_TRACE_LEVEL_INFO,
4354 "%s: Scan allowed", __func__);
4355 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304356}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004357
4358/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004359 * FUNCTION: wlan_hdd_cfg80211_scan
4360 * this scan respond to scan trigger and update cfg80211 scan database
4361 * later, scan dump command can be used to recieve scan results
4362 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004363int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4364#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4365 struct net_device *dev,
4366#endif
4367 struct cfg80211_scan_request *request)
4368{
4369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4370 struct net_device *dev = request->wdev->netdev;
4371#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4374 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304375 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 tCsrScanRequest scanRequest;
4377 tANI_U8 *channelList = NULL, i;
4378 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304379 int status;
4380 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004382
4383 ENTER();
4384
4385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4386 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304388 status = wlan_hdd_validate_context(pHddCtx);
4389
4390 if (0 != status)
4391 {
4392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4393 "%s: HDD context is not valid", __func__);
4394 return status;
4395 }
4396
4397 cfg_param = pHddCtx->cfg_ini;
4398 pScanInfo = &pHddCtx->scan_info;
4399
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004400 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004401 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004402 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004403 {
4404 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004405 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4406 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004407 return -EBUSY;
4408 }
4409
Jeff Johnson295189b2012-06-20 16:38:30 -07004410#ifdef WLAN_BTAMP_FEATURE
4411 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004412 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004413 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 "%s: No scanning when AMP is on", __func__);
4416 return -EOPNOTSUPP;
4417 }
4418#endif
4419 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 "%s: Not scanning on device_mode = %d",
4424 __func__, pAdapter->device_mode);
4425 return -EOPNOTSUPP;
4426 }
4427
4428 if (TRUE == pScanInfo->mScanPending)
4429 {
4430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004431 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004432 }
4433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304434 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004435 //Channel and action frame is pending
4436 //Otherwise Cancel Remain On Channel and allow Scan
4437 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004438 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004439 {
4440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4441 return -EBUSY;
4442 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004443#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004444 /* if tdls disagree scan right now, return immediately.
4445 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4446 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4447 */
4448 status = wlan_hdd_tdls_scan_callback (pAdapter,
4449 wiphy,
4450#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4451 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004452#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004453 request);
4454 if(status <= 0)
4455 {
4456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4457 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004458 }
4459#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004460
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4462 {
4463 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004464 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4468 {
4469 hddLog(VOS_TRACE_LEVEL_WARN,
4470 "%s: MAX TM Level Scan not allowed", __func__);
4471 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304472 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004473 }
4474 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4475
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004476 /* Check if scan is allowed at this point of time.
4477 */
4478 if (!hdd_isScanAllowed(pHddCtx))
4479 {
4480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4481 return -EBUSY;
4482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304483
Jeff Johnson295189b2012-06-20 16:38:30 -07004484 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4485
4486 if (NULL != request)
4487 {
4488 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304489 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004490
4491 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4492 * Becasue of this, driver is assuming that this is not wildcard scan and so
4493 * is not aging out the scan results.
4494 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004495 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 {
4497 request->n_ssids = 0;
4498 }
4499
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004500 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 {
4502 tCsrSSIDInfo *SsidInfo;
4503 int j;
4504 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4505 /* Allocate num_ssid tCsrSSIDInfo structure */
4506 SsidInfo = scanRequest.SSIDs.SSIDList =
4507 ( tCsrSSIDInfo *)vos_mem_malloc(
4508 request->n_ssids*sizeof(tCsrSSIDInfo));
4509
4510 if(NULL == scanRequest.SSIDs.SSIDList)
4511 {
4512 hddLog(VOS_TRACE_LEVEL_ERROR,
4513 "memory alloc failed SSIDInfo buffer");
4514 return -ENOMEM;
4515 }
4516
4517 /* copy all the ssid's and their length */
4518 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4519 {
4520 /* get the ssid length */
4521 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4522 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4523 SsidInfo->SSID.length);
4524 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4525 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4526 j, SsidInfo->SSID.ssId);
4527 }
4528 /* set the scan type to active */
4529 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4530 }
4531 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4532 {
4533 /* set the scan type to active */
4534 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4535 }
4536 else
4537 {
4538 /*Set the scan type to default type, in this case it is ACTIVE*/
4539 scanRequest.scanType = pScanInfo->scan_mode;
4540 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4543 }
4544 else
4545 {
4546 /* set the scan type to active */
4547 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4548 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4549
4550 /* set min and max channel time to zero */
4551 scanRequest.minChnTime = 0;
4552 scanRequest.maxChnTime = 0;
4553 }
4554
4555 /* set BSSType to default type */
4556 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4557
4558 /*TODO: scan the requested channels only*/
4559
4560 /*Right now scanning all the channels */
4561 if( request )
4562 {
4563 if( request->n_channels )
4564 {
4565 channelList = vos_mem_malloc( request->n_channels );
4566 if( NULL == channelList )
4567 {
4568 status = -ENOMEM;
4569 goto free_mem;
4570 }
4571
4572 for( i = 0 ; i < request->n_channels ; i++ )
4573 channelList[i] = request->channels[i]->hw_value;
4574 }
4575
4576 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4577 scanRequest.ChannelInfo.ChannelList = channelList;
4578
4579 /* set requestType to full scan */
4580 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581
4582 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004583 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004585 */
4586
4587 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588 * and in that case driver shoudnt flush scan results. If
4589 * driver flushes the scan results here and unfortunately if
4590 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004591 * fails which is not desired
4592 */
4593
4594 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4595 {
4596 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4597 pAdapter->sessionId );
4598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004599
4600 if( request->ie_len )
4601 {
4602 /* save this for future association (join requires this) */
4603 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4604 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4605 pScanInfo->scanAddIE.length = request->ie_len;
4606
4607 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004608 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4609 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004610 )
4611 {
4612 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4613 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4614 }
4615
4616 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4617 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4618
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4620 request->ie_len);
4621 if (pP2pIe != NULL)
4622 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004623#ifdef WLAN_FEATURE_P2P_DEBUG
4624 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4625 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4626 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4627 {
4628 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4629 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4630 "Go nego completed to Connection is started");
4631 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4632 "for 8way Handshake");
4633 }
4634 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4635 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4636 {
4637 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4639 "Disconnected state to Connection is started");
4640 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4641 "for 4way Handshake");
4642 }
4643#endif
4644
Jeff Johnsone7245742012-09-05 17:12:55 -07004645 /* no_cck will be set during p2p find to disable 11b rates */
4646 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 hddLog(VOS_TRACE_LEVEL_INFO,
4649 "%s: This is a P2P Search", __func__);
4650 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004651
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4653 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004654 /* set requestType to P2P Discovery */
4655 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004656 }
4657
4658 /*
4659 Skip Dfs Channel in case of P2P Search
4660 if it is set in ini file
4661 */
4662 if(cfg_param->skipDfsChnlInP2pSearch)
4663 {
4664 scanRequest.skipDfsChnlInP2pSearch = 1;
4665 }
4666 else
4667 {
4668 scanRequest.skipDfsChnlInP2pSearch = 0;
4669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004670
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 }
4672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 }
4674 }
4675
4676 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4677
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004678 /* acquire the wakelock to avoid the apps suspend during the scan. To
4679 * address the following issues.
4680 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4681 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4682 * for long time, this result in apps running at full power for long time.
4683 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4684 * be stuck in full power because of resume BMPS
4685 */
4686 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004687
4688 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 pAdapter->sessionId, &scanRequest, &scanId,
4690 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004691
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 if (eHAL_STATUS_SUCCESS != status)
4693 {
4694 hddLog(VOS_TRACE_LEVEL_ERROR,
4695 "%s: sme_ScanRequest returned error %d", __func__, status);
4696 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004697 if(eHAL_STATUS_RESOURCES == status)
4698 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004699 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 -07004700 status = -EBUSY;
4701 } else {
4702 status = -EIO;
4703 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004704 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 goto free_mem;
4706 }
4707
4708 pScanInfo->mScanPending = TRUE;
4709 pAdapter->request = request;
4710 pScanInfo->scanId = scanId;
4711
4712 complete(&pScanInfo->scan_req_completion_event);
4713
4714free_mem:
4715 if( scanRequest.SSIDs.SSIDList )
4716 {
4717 vos_mem_free(scanRequest.SSIDs.SSIDList);
4718 }
4719
4720 if( channelList )
4721 vos_mem_free( channelList );
4722
4723 EXIT();
4724
4725 return status;
4726}
4727
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004728
4729void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4730{
4731 v_U8_t iniDot11Mode =
4732 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4733 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4734
4735 switch ( iniDot11Mode )
4736 {
4737 case eHDD_DOT11_MODE_AUTO:
4738 case eHDD_DOT11_MODE_11ac:
4739 case eHDD_DOT11_MODE_11ac_ONLY:
4740#ifdef WLAN_FEATURE_11AC
4741 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4742#else
4743 hddDot11Mode = eHDD_DOT11_MODE_11n;
4744#endif
4745 break;
4746 case eHDD_DOT11_MODE_11n:
4747 case eHDD_DOT11_MODE_11n_ONLY:
4748 hddDot11Mode = eHDD_DOT11_MODE_11n;
4749 break;
4750 default:
4751 hddDot11Mode = iniDot11Mode;
4752 break;
4753 }
4754 /* This call decides required channel bonding mode */
4755 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4756 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4757 operationChannel);
4758}
4759
Jeff Johnson295189b2012-06-20 16:38:30 -07004760/*
4761 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304762 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304764int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004765 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004766{
4767 int status = 0;
4768 hdd_wext_state_t *pWextState;
4769 v_U32_t roamId;
4770 tCsrRoamProfile *pRoamProfile;
4771 eMib_dot11DesiredBssType connectedBssType;
4772 eCsrAuthType RSNAuthType;
4773
4774 ENTER();
4775
4776 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304777
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4779 {
4780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4781 return -EINVAL;
4782 }
4783
4784 pRoamProfile = &pWextState->roamProfile;
4785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304786 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004788 int ret = 0;
4789 hdd_station_ctx_t *pHddStaCtx;
4790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4791 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4792
4793 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4794 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4795 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 {
4797 /* Issue disconnect to CSR */
4798 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304799 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4801 pAdapter->sessionId,
4802 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4803 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004804 ret = wait_for_completion_interruptible_timeout(
4805 &pAdapter->disconnect_comp_var,
4806 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4807 if (0 == ret)
4808 {
4809 VOS_ASSERT(0);
4810 }
4811 }
4812 }
4813 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4814 {
4815 ret = wait_for_completion_interruptible_timeout(
4816 &pAdapter->disconnect_comp_var,
4817 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4818 if (0 == ret)
4819 {
4820 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 }
4822 }
4823
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304824 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4826 {
4827 /*QoS not enabled in cfg file*/
4828 pRoamProfile->uapsd_mask = 0;
4829 }
4830 else
4831 {
4832 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304833 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4835 }
4836
4837 pRoamProfile->SSIDs.numOfSSIDs = 1;
4838 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4839 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4842 ssid, ssid_len);
4843
4844 if (bssid)
4845 {
4846 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4847 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4848 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304849 /* Save BSSID in seperate variable as well, as RoamProfile
4850 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 case of join failure we should send valid BSSID to supplicant
4852 */
4853 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4854 WNI_CFG_BSSID_LEN);
4855 }
4856
4857 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4858 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304859 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 /*set gen ie*/
4861 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4862 /*set auth*/
4863 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004865#ifdef FEATURE_WLAN_WAPI
4866 if (pAdapter->wapi_info.nWapiMode)
4867 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004868 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004869 switch (pAdapter->wapi_info.wapiAuthMode)
4870 {
4871 case WAPI_AUTH_MODE_PSK:
4872 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004873 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 pAdapter->wapi_info.wapiAuthMode);
4875 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4876 break;
4877 }
4878 case WAPI_AUTH_MODE_CERT:
4879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004880 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 pAdapter->wapi_info.wapiAuthMode);
4882 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4883 break;
4884 }
4885 } // End of switch
4886 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4887 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4888 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004889 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 pRoamProfile->AuthType.numEntries = 1;
4891 pRoamProfile->EncryptionType.numEntries = 1;
4892 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4893 pRoamProfile->mcEncryptionType.numEntries = 1;
4894 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4895 }
4896 }
4897#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304898#ifdef WLAN_FEATURE_GTK_OFFLOAD
4899 /* Initializing gtkOffloadRequestParams */
4900 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4901 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4902 {
4903 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4904 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4905 0, sizeof (tSirGtkOffloadParams));
4906 }
4907#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 pRoamProfile->csrPersona = pAdapter->device_mode;
4909
Jeff Johnson32d95a32012-09-10 13:15:23 -07004910 if( operatingChannel )
4911 {
4912 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4913 pRoamProfile->ChannelInfo.numOfChannels = 1;
4914 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004915 else
4916 {
4917 pRoamProfile->ChannelInfo.ChannelList = NULL;
4918 pRoamProfile->ChannelInfo.numOfChannels = 0;
4919 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004920 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4921 {
4922 hdd_select_cbmode(pAdapter,operatingChannel);
4923 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004924 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4925 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304926 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004927 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004928 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4929 */
4930 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4931 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4932 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304933
4934 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 pAdapter->sessionId, pRoamProfile, &roamId);
4936
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004937 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304938 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4939
4940 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4942 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4943 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304944 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004945 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304946 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004947
4948 pRoamProfile->ChannelInfo.ChannelList = NULL;
4949 pRoamProfile->ChannelInfo.numOfChannels = 0;
4950
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 }
4952 else
4953 {
4954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4955 return -EINVAL;
4956 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004957 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 return status;
4959}
4960
4961/*
4962 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4963 * This function is used to set the authentication type (OPEN/SHARED).
4964 *
4965 */
4966static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4967 enum nl80211_auth_type auth_type)
4968{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304969 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4971
4972 ENTER();
4973
4974 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304975 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304978 hddLog(VOS_TRACE_LEVEL_INFO,
4979 "%s: set authentication type to AUTOSWITCH", __func__);
4980 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4981 break;
4982
4983 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004984#ifdef WLAN_FEATURE_VOWIFI_11R
4985 case NL80211_AUTHTYPE_FT:
4986#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304987 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004988 "%s: set authentication type to OPEN", __func__);
4989 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4990 break;
4991
4992 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304993 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004994 "%s: set authentication type to SHARED", __func__);
4995 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4996 break;
4997#ifdef FEATURE_WLAN_CCX
4998 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304999 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005000 "%s: set authentication type to CCKM WPA", __func__);
5001 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5002 break;
5003#endif
5004
5005
5006 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007 hddLog(VOS_TRACE_LEVEL_ERROR,
5008 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 auth_type);
5010 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5011 return -EINVAL;
5012 }
5013
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 pHddStaCtx->conn_info.authType;
5016 return 0;
5017}
5018
5019/*
5020 * FUNCTION: wlan_hdd_set_akm_suite
5021 * This function is used to set the key mgmt type(PSK/8021x).
5022 *
5023 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305024static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005025 u32 key_mgmt
5026 )
5027{
5028 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5029 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305030
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 /*set key mgmt type*/
5032 switch(key_mgmt)
5033 {
5034 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305035#ifdef WLAN_FEATURE_VOWIFI_11R
5036 case WLAN_AKM_SUITE_FT_PSK:
5037#endif
5038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 __func__);
5040 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5041 break;
5042
5043 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305044#ifdef WLAN_FEATURE_VOWIFI_11R
5045 case WLAN_AKM_SUITE_FT_8021X:
5046#endif
5047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005048 __func__);
5049 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5050 break;
5051#ifdef FEATURE_WLAN_CCX
5052#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5053#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5054 case WLAN_AKM_SUITE_CCKM:
5055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5056 __func__);
5057 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5058 break;
5059#endif
5060
5061 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 __func__, key_mgmt);
5064 return -EINVAL;
5065
5066 }
5067 return 0;
5068}
5069
5070/*
5071 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305072 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005073 * (NONE/WEP40/WEP104/TKIP/CCMP).
5074 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5076 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 bool ucast
5078 )
5079{
5080 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305081 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5083
5084 ENTER();
5085
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305086 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 __func__, cipher);
5090 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5091 }
5092 else
5093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 {
5098 case IW_AUTH_CIPHER_NONE:
5099 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5100 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305101
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305103 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305107 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 case WLAN_CIPHER_SUITE_TKIP:
5111 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5112 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 case WLAN_CIPHER_SUITE_CCMP:
5115 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5116 break;
5117#ifdef FEATURE_WLAN_WAPI
5118 case WLAN_CIPHER_SUITE_SMS4:
5119 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5120 break;
5121#endif
5122
5123#ifdef FEATURE_WLAN_CCX
5124 case WLAN_CIPHER_SUITE_KRK:
5125 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5126 break;
5127#endif
5128 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 __func__, cipher);
5131 return -EOPNOTSUPP;
5132 }
5133 }
5134
5135 if (ucast)
5136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 __func__, encryptionType);
5139 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5140 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 encryptionType;
5143 }
5144 else
5145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305146 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005147 __func__, encryptionType);
5148 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5149 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5150 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5151 }
5152
5153 return 0;
5154}
5155
5156
5157/*
5158 * FUNCTION: wlan_hdd_cfg80211_set_ie
5159 * This function is used to parse WPA/RSN IE's.
5160 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305161int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5162 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 size_t ie_len
5164 )
5165{
5166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5167 u8 *genie = ie;
5168 v_U16_t remLen = ie_len;
5169#ifdef FEATURE_WLAN_WAPI
5170 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5171 u16 *tmp;
5172 v_U16_t akmsuiteCount;
5173 int *akmlist;
5174#endif
5175 ENTER();
5176
5177 /* clear previous assocAddIE */
5178 pWextState->assocAddIE.length = 0;
5179 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5180
5181 while (remLen >= 2)
5182 {
5183 v_U16_t eLen = 0;
5184 v_U8_t elementId;
5185 elementId = *genie++;
5186 eLen = *genie++;
5187 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188
5189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305191
5192 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005195 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 -07005196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 "%s: Invalid WPA IE", __func__);
5199 return -EINVAL;
5200 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 {
5203 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305206
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5208 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005209 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5210 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 VOS_ASSERT(0);
5212 return -ENOMEM;
5213 }
5214 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5215 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5216 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305217
Jeff Johnson295189b2012-06-20 16:38:30 -07005218 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5219 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5220 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5221 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305222 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5223 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5225 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5226 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5227 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5228 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5229 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305230 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5231 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 /*Consider P2P IE, only for P2P Client */
5233 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5234 {
5235 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305236 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305238
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5240 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005241 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5242 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 VOS_ASSERT(0);
5244 return -ENOMEM;
5245 }
5246 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5247 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5248 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305249
Jeff Johnson295189b2012-06-20 16:38:30 -07005250 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5251 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5252 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005253#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305254 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5255 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005256 /*Consider WFD IE, only for P2P Client */
5257 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5258 {
5259 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305260 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005261 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5264 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005265 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5266 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 VOS_ASSERT(0);
5268 return -ENOMEM;
5269 }
5270 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5271 // WPS IE + P2P IE + WFD IE
5272 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5273 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305274
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5276 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5277 }
5278#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005279 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305280 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005281 HS20_OUI_TYPE_SIZE)) )
5282 {
5283 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305284 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005285 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005286
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005287 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5288 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005289 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5290 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005291 VOS_ASSERT(0);
5292 return -ENOMEM;
5293 }
5294 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5295 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005296
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005297 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5298 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5299 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300
Jeff Johnson295189b2012-06-20 16:38:30 -07005301 break;
5302 case DOT11F_EID_RSN:
5303 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5304 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5305 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5306 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5307 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5308 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005309 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5310 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305311 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005312 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305313 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005314 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305315
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005316 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5317 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005318 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5319 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005320 VOS_ASSERT(0);
5321 return -ENOMEM;
5322 }
5323 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5324 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305325
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005326 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5327 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5328 break;
5329 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005330#ifdef FEATURE_WLAN_WAPI
5331 case WLAN_EID_WAPI:
5332 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5333 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5334 pAdapter->wapi_info.nWapiMode);
5335 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305336 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 akmsuiteCount = WPA_GET_LE16(tmp);
5338 tmp = tmp + 1;
5339 akmlist = (int *)(tmp);
5340 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5341 {
5342 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5343 }
5344 else
5345 {
5346 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5347 VOS_ASSERT(0);
5348 return -EINVAL;
5349 }
5350
5351 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5352 {
5353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005354 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305358 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005360 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5362 }
5363 break;
5364#endif
5365 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305366 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005368 /* when Unknown IE is received we should break and continue
5369 * to the next IE in the buffer instead we were returning
5370 * so changing this to break */
5371 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 }
5373 genie += eLen;
5374 remLen -= eLen;
5375 }
5376 EXIT();
5377 return 0;
5378}
5379
5380/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305381 * FUNCTION: hdd_isWPAIEPresent
5382 * Parse the received IE to find the WPA IE
5383 *
5384 */
5385static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5386{
5387 v_U8_t eLen = 0;
5388 v_U16_t remLen = ie_len;
5389 v_U8_t elementId = 0;
5390
5391 while (remLen >= 2)
5392 {
5393 elementId = *ie++;
5394 eLen = *ie++;
5395 remLen -= 2;
5396 if (eLen > remLen)
5397 {
5398 hddLog(VOS_TRACE_LEVEL_ERROR,
5399 "%s: IE length is wrong %d", __func__, eLen);
5400 return FALSE;
5401 }
5402 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5403 {
5404 /* OUI - 0x00 0X50 0XF2
5405 WPA Information Element - 0x01
5406 WPA version - 0x01*/
5407 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5408 return TRUE;
5409 }
5410 ie += eLen;
5411 remLen -= eLen;
5412 }
5413 return FALSE;
5414}
5415
5416/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 * parameters during connect operation.
5420 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305421int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 struct cfg80211_connect_params *req
5423 )
5424{
5425 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 ENTER();
5428
5429 /*set wpa version*/
5430 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5431
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305432 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 {
5434 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305436 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305438 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 * since p2p ie is also put in same buffer.
5440 * */
5441 {
5442 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5443 }
5444 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5445 {
5446 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5447 }
5448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305449
5450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 pWextState->wpaVersion);
5452
5453 /*set authentication type*/
5454 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5455
5456 if (0 > status)
5457 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305458 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 "%s: failed to set authentication type ", __func__);
5460 return status;
5461 }
5462
5463 /*set key mgmt type*/
5464 if (req->crypto.n_akm_suites)
5465 {
5466 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5467 if (0 > status)
5468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 __func__);
5471 return status;
5472 }
5473 }
5474
5475 /*set pairwise cipher type*/
5476 if (req->crypto.n_ciphers_pairwise)
5477 {
5478 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5479 req->crypto.ciphers_pairwise[0], true);
5480 if (0 > status)
5481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 "%s: failed to set unicast cipher type", __func__);
5484 return status;
5485 }
5486 }
5487 else
5488 {
5489 /*Reset previous cipher suite to none*/
5490 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5491 if (0 > status)
5492 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305493 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 "%s: failed to set unicast cipher type", __func__);
5495 return status;
5496 }
5497 }
5498
5499 /*set group cipher type*/
5500 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5501 false);
5502
5503 if (0 > status)
5504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 __func__);
5507 return status;
5508 }
5509
Chet Lanctot186b5732013-03-18 10:26:30 -07005510#ifdef WLAN_FEATURE_11W
5511 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5512#endif
5513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5515 if (req->ie_len)
5516 {
5517 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5518 if ( 0 > status)
5519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 __func__);
5522 return status;
5523 }
5524 }
5525
5526 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 {
5529 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5530 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5531 )
5532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305533 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 __func__);
5538 return -EOPNOTSUPP;
5539 }
5540 else
5541 {
5542 u8 key_len = req->key_len;
5543 u8 key_idx = req->key_idx;
5544
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305545 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 && (CSR_MAX_NUM_KEY > key_idx)
5547 )
5548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305549 hddLog(VOS_TRACE_LEVEL_INFO,
5550 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 __func__, key_idx, key_len);
5552 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305555 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 (u8)key_len;
5557 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5558 }
5559 }
5560 }
5561 }
5562
5563 return status;
5564}
5565
5566/*
5567 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 * parameters during connect operation.
5570 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 struct net_device *ndev,
5573 struct cfg80211_connect_params *req
5574 )
5575{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305576 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5579 hdd_context_t *pHddCtx = NULL;
5580
5581 ENTER();
5582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5585
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5587 status = wlan_hdd_validate_context(pHddCtx);
5588
5589 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5592 "%s: HDD context is not valid", __func__);
5593 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 }
5595
5596#ifdef WLAN_BTAMP_FEATURE
5597 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305598 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305600 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005602 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 }
5604#endif
5605 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305606 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005607
5608 if ( 0 > status)
5609 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 __func__);
5612 return status;
5613 }
5614
5615 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005616 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5618 (vos_concurrent_sessions_running()))
5619 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305620 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 }
5622
Mohit Khanna765234a2012-09-11 15:08:35 -07005623 if ( req->channel )
5624 {
5625 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5626 req->ssid_len, req->bssid,
5627 req->channel->hw_value);
5628 }
5629 else
5630 {
5631 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305632 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005634
5635 if (0 > status)
5636 {
5637 //ReEnable BMPS if disabled
5638 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5639 (NULL != pHddCtx))
5640 {
5641 //ReEnable Bmps and Imps back
5642 hdd_enable_bmps_imps(pHddCtx);
5643 }
5644
5645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5646 return status;
5647 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305648 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 EXIT();
5650 return status;
5651}
5652
5653
5654/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305655 * FUNCTION: wlan_hdd_disconnect
5656 * This function is used to issue a disconnect request to SME
5657 */
5658int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5659{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305660 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305661 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305662 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5663
5664 status = wlan_hdd_validate_context(pHddCtx);
5665
5666 if (0 != status)
5667 {
5668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5669 "%s: HDD context is not valid", __func__);
5670 return status;
5671 }
5672
5673 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305674 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305675 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305676
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305677 /*issue disconnect*/
5678 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5679 pAdapter->sessionId, reason);
5680
5681 if ( 0 != status )
5682 {
5683 hddLog(VOS_TRACE_LEVEL_ERROR,
5684 "%s csrRoamDisconnect failure, returned %d \n",
5685 __func__, (int)status );
5686 return -EINVAL;
5687 }
5688 wait_for_completion_interruptible_timeout(
5689 &pAdapter->disconnect_comp_var,
5690 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5691 /*stop tx queues*/
5692 netif_tx_disable(pAdapter->dev);
5693 netif_carrier_off(pAdapter->dev);
5694 return status;
5695}
5696
5697
5698/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 * FUNCTION: wlan_hdd_cfg80211_disconnect
5700 * This function is used to issue a disconnect request to SME
5701 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305702static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 struct net_device *dev,
5704 u16 reason
5705 )
5706{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5708 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305710 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005712 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305713#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005714 tANI_U8 staIdx;
5715#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305716
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305718
5719 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 __func__,pAdapter->device_mode);
5721
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5723 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005724
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305725 status = wlan_hdd_validate_context(pHddCtx);
5726
5727 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5730 "%s: HDD context is not valid", __func__);
5731 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305733
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 if (NULL != pRoamProfile)
5735 {
5736 /*issue disconnect request to SME, if station is in connected state*/
5737 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5738 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305741 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 switch(reason)
5743 {
5744 case WLAN_REASON_MIC_FAILURE:
5745 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5746 break;
5747
5748 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5749 case WLAN_REASON_DISASSOC_AP_BUSY:
5750 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5751 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5752 break;
5753
5754 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5755 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5756 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5757 break;
5758
5759 case WLAN_REASON_DEAUTH_LEAVING:
5760 default:
5761 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5762 break;
5763 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305764 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5765 pScanInfo = &pHddCtx->scan_info;
5766 if (pScanInfo->mScanPending)
5767 {
5768 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5769 "Aborting Scan");
5770 hdd_abort_mac_scan(pHddCtx);
5771 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005772
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005773#ifdef FEATURE_WLAN_TDLS
5774 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005775 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005776 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005777 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5778 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005779 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005780 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005781 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005782 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005783 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005784 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005785 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005786 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005787 pAdapter->sessionId,
5788 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005789 }
5790 }
5791#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305792 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5793 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005794 {
5795 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305796 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 __func__, (int)status );
5798 return -EINVAL;
5799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 }
5801 }
5802 else
5803 {
5804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5805 }
5806
5807 return status;
5808}
5809
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305810
Jeff Johnson295189b2012-06-20 16:38:30 -07005811/*
5812 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305813 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 * settings in IBSS mode.
5815 */
5816static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305817 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 struct cfg80211_ibss_params *params
5819 )
5820{
5821 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305822 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5824 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 ENTER();
5827
5828 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5829
5830 if (params->ie_len && ( NULL != params->ie) )
5831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305832 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 {
5834 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5835 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5836 }
5837 else
5838 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005839 tDot11fIEWPA dot11WPAIE;
5840 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5841
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005843 // Unpack the WPA IE
5844 //Skip past the EID byte and length byte - and four byte WiFi OUI
5845 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5846 &params->ie[2+4],
5847 params->ie[1] - 4,
5848 &dot11WPAIE);
5849 /*Extract the multicast cipher, the encType for unicast
5850 cipher for wpa-none is none*/
5851 encryptionType =
5852 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 }
5854 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5855
5856 if (0 > status)
5857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 __func__);
5860 return status;
5861 }
5862 }
5863
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 pWextState->roamProfile.AuthType.authType[0] =
5865 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005866 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5867
5868 if (params->privacy)
5869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870 /* Security enabled IBSS, At this time there is no information available
5871 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305875 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 *enable privacy bit in beacons */
5877
5878 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5879 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005880 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5881 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5883 pWextState->roamProfile.EncryptionType.numEntries = 1;
5884 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 return status;
5886}
5887
5888/*
5889 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305890 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 struct net_device *dev,
5894 struct cfg80211_ibss_params *params
5895 )
5896{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5899 tCsrRoamProfile *pRoamProfile;
5900 int status;
5901 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305902 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005903
5904 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305905
5906 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5908
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305909 status = wlan_hdd_validate_context(pHddCtx);
5910
5911 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5914 "%s: HDD context is not valid", __func__);
5915 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 }
5917
5918 if (NULL == pWextState)
5919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 __func__);
5922 return -EIO;
5923 }
5924
5925 pRoamProfile = &pWextState->roamProfile;
5926
5927 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5928 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305929 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 "%s Interface type is not set to IBSS \n", __func__);
5931 return -EINVAL;
5932 }
5933
5934 /* Set Channel */
5935 if (NULL != params->channel)
5936 {
5937 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005938 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5939 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5940 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5941 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005942
5943 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305944 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 ieee80211_frequency_to_channel(params->channel->center_freq);
5946
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005947
5948 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5949 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5952 __func__);
5953 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005955
5956 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005958 if (channelNum == validChan[indx])
5959 {
5960 break;
5961 }
5962 }
5963 if (indx >= numChans)
5964 {
5965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 __func__, channelNum);
5967 return -EINVAL;
5968 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005969 /* Set the Operational Channel */
5970 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5971 channelNum);
5972 pRoamProfile->ChannelInfo.numOfChannels = 1;
5973 pHddStaCtx->conn_info.operationChannel = channelNum;
5974 pRoamProfile->ChannelInfo.ChannelList =
5975 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 }
5977
5978 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305979 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 if (status < 0)
5981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 __func__);
5984 return status;
5985 }
5986
5987 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305988 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005989 params->ssid_len, params->bssid,
5990 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005991
5992 if (0 > status)
5993 {
5994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5995 return status;
5996 }
5997
5998 return 0;
5999}
6000
6001/*
6002 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306003 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306005static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 struct net_device *dev
6007 )
6008{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6011 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306012 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6013 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006014
6015 ENTER();
6016
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306017 status = wlan_hdd_validate_context(pHddCtx);
6018
6019 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6022 "%s: HDD context is not valid", __func__);
6023 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006024 }
6025
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6027 if (NULL == pWextState)
6028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306029 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 __func__);
6031 return -EIO;
6032 }
6033
6034 pRoamProfile = &pWextState->roamProfile;
6035
6036 /* Issue disconnect only if interface type is set to IBSS */
6037 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6038 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 __func__);
6041 return -EINVAL;
6042 }
6043
6044 /* Issue Disconnect request */
6045 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6046 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6047 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6048
6049 return 0;
6050}
6051
6052/*
6053 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6054 * This function is used to set the phy parameters
6055 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6056 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 u32 changed)
6059{
6060 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6061 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306062 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006063
6064 ENTER();
6065
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306066 status = wlan_hdd_validate_context(pHddCtx);
6067
6068 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006069 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6071 "%s: HDD context is not valid", __func__);
6072 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006073 }
6074
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6076 {
6077 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6078 WNI_CFG_RTS_THRESHOLD_STAMAX :
6079 wiphy->rts_threshold;
6080
6081 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306084 hddLog(VOS_TRACE_LEVEL_ERROR,
6085 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 __func__, rts_threshold);
6087 return -EINVAL;
6088 }
6089
6090 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6091 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306092 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306094 hddLog(VOS_TRACE_LEVEL_ERROR,
6095 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 __func__, rts_threshold);
6097 return -EIO;
6098 }
6099
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 rts_threshold);
6102 }
6103
6104 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6105 {
6106 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6107 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6108 wiphy->frag_threshold;
6109
6110 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306111 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306113 hddLog(VOS_TRACE_LEVEL_ERROR,
6114 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 frag_threshold);
6116 return -EINVAL;
6117 }
6118
6119 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6120 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306121 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 hddLog(VOS_TRACE_LEVEL_ERROR,
6124 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 __func__, frag_threshold);
6126 return -EIO;
6127 }
6128
6129 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6130 frag_threshold);
6131 }
6132
6133 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6134 || (changed & WIPHY_PARAM_RETRY_LONG))
6135 {
6136 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6137 wiphy->retry_short :
6138 wiphy->retry_long;
6139
6140 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6141 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6142 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 __func__, retry_value);
6145 return -EINVAL;
6146 }
6147
6148 if (changed & WIPHY_PARAM_RETRY_SHORT)
6149 {
6150 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6151 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306152 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306154 hddLog(VOS_TRACE_LEVEL_ERROR,
6155 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 __func__, retry_value);
6157 return -EIO;
6158 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306159 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 __func__, retry_value);
6161 }
6162 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6163 {
6164 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6165 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306166 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306168 hddLog(VOS_TRACE_LEVEL_ERROR,
6169 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 __func__, retry_value);
6171 return -EIO;
6172 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306173 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 __func__, retry_value);
6175 }
6176 }
6177
6178 return 0;
6179}
6180
6181/*
6182 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6183 * This function is used to set the txpower
6184 */
6185static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6186#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306187 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006188#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306189 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006190#endif
6191 int dbm)
6192{
6193 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306194 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006195 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6196 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306197 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006198
6199 ENTER();
6200
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306201 status = wlan_hdd_validate_context(pHddCtx);
6202
6203 if (0 != status)
6204 {
6205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6206 "%s: HDD context is not valid", __func__);
6207 return status;
6208 }
6209
6210 hHal = pHddCtx->hHal;
6211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6213 dbm, ccmCfgSetCallback,
6214 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6218 return -EIO;
6219 }
6220
6221 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6222 dbm);
6223
6224 switch(type)
6225 {
6226 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6227 /* Fall through */
6228 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6229 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6232 __func__);
6233 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 }
6235 break;
6236 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 __func__);
6239 return -EOPNOTSUPP;
6240 break;
6241 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6243 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 return -EIO;
6245 }
6246
6247 return 0;
6248}
6249
6250/*
6251 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6252 * This function is used to read the txpower
6253 */
6254static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6255{
6256
6257 hdd_adapter_t *pAdapter;
6258 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306259 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006260
Jeff Johnsone7245742012-09-05 17:12:55 -07006261 ENTER();
6262
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306263 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006264
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306265 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006266 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6268 "%s: HDD context is not valid", __func__);
6269 *dbm = 0;
6270 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006271 }
6272
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6274 if (NULL == pAdapter)
6275 {
6276 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6277 return -ENOENT;
6278 }
6279
6280 wlan_hdd_get_classAstats(pAdapter);
6281 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6282
Jeff Johnsone7245742012-09-05 17:12:55 -07006283 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 return 0;
6285}
6286
6287static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6288 u8* mac, struct station_info *sinfo)
6289{
6290 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6291 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6292 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6293 tANI_U8 rate_flags;
6294
6295 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6296 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006297
6298 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6299 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6300 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6301 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6302 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6303 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6304 tANI_U16 maxRate = 0;
6305 tANI_U16 myRate;
6306 tANI_U16 currentRate = 0;
6307 tANI_U8 maxSpeedMCS = 0;
6308 tANI_U8 maxMCSIdx = 0;
6309 tANI_U8 rateFlag = 1;
6310 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006311 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306312 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006313
Leo Chang6f8870f2013-03-26 18:11:36 -07006314#ifdef WLAN_FEATURE_11AC
6315 tANI_U32 vht_mcs_map;
6316 eDataRate11ACMaxMcs vhtMaxMcs;
6317#endif /* WLAN_FEATURE_11AC */
6318
Jeff Johnsone7245742012-09-05 17:12:55 -07006319 ENTER();
6320
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6322 (0 == ssidlen))
6323 {
6324 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6325 " Invalid ssidlen, %d", __func__, ssidlen);
6326 /*To keep GUI happy*/
6327 return 0;
6328 }
6329
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306330 status = wlan_hdd_validate_context(pHddCtx);
6331
6332 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006333 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6335 "%s: HDD context is not valid", __func__);
6336 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006337 }
6338
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6340 sinfo->filled |= STATION_INFO_SIGNAL;
6341
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006342 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6344
6345 //convert to the UI units of 100kbps
6346 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6347
6348#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006349 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 -07006350 sinfo->signal,
6351 pCfg->reportMaxLinkSpeed,
6352 myRate,
6353 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006354 (int) pCfg->linkSpeedRssiMid,
6355 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006356 (int) rate_flags,
6357 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006358#endif //LINKSPEED_DEBUG_ENABLED
6359
6360 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6361 {
6362 // we do not want to necessarily report the current speed
6363 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6364 {
6365 // report the max possible speed
6366 rssidx = 0;
6367 }
6368 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6369 {
6370 // report the max possible speed with RSSI scaling
6371 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6372 {
6373 // report the max possible speed
6374 rssidx = 0;
6375 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006376 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 {
6378 // report middle speed
6379 rssidx = 1;
6380 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006381 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6382 {
6383 // report middle speed
6384 rssidx = 2;
6385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 else
6387 {
6388 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006389 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 }
6391 }
6392 else
6393 {
6394 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6395 hddLog(VOS_TRACE_LEVEL_ERROR,
6396 "%s: Invalid value for reportMaxLinkSpeed: %u",
6397 __func__, pCfg->reportMaxLinkSpeed);
6398 rssidx = 0;
6399 }
6400
6401 maxRate = 0;
6402
6403 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306404 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6405 OperationalRates, &ORLeng))
6406 {
6407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6408 /*To keep GUI happy*/
6409 return 0;
6410 }
6411
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 for (i = 0; i < ORLeng; i++)
6413 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006414 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 {
6416 /* Validate Rate Set */
6417 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6418 {
6419 currentRate = supported_data_rate[j].supported_rate[rssidx];
6420 break;
6421 }
6422 }
6423 /* Update MAX rate */
6424 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6425 }
6426
6427 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306428 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6429 ExtendedRates, &ERLeng))
6430 {
6431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6432 /*To keep GUI happy*/
6433 return 0;
6434 }
6435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 for (i = 0; i < ERLeng; i++)
6437 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006438 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 {
6440 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6441 {
6442 currentRate = supported_data_rate[j].supported_rate[rssidx];
6443 break;
6444 }
6445 }
6446 /* Update MAX rate */
6447 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 /* Get MCS Rate Set -- but only if we are connected at MCS
6450 rates or if we are always reporting max speed or if we have
6451 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006452 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306454 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6455 MCSRates, &MCSLeng))
6456 {
6457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6458 /*To keep GUI happy*/
6459 return 0;
6460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006462#ifdef WLAN_FEATURE_11AC
6463 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306464 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006466 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306467 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006468 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006470 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006472 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006474 maxMCSIdx = 7;
6475 }
6476 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6477 {
6478 maxMCSIdx = 8;
6479 }
6480 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6481 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306482 //VHT20 is supporting 0~8
6483 if (rate_flags & eHAL_TX_RATE_VHT20)
6484 maxMCSIdx = 8;
6485 else
6486 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006487 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306488
6489 if (rate_flags & eHAL_TX_RATE_VHT80)
6490 {
6491 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6492 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6493 }
6494 else if (rate_flags & eHAL_TX_RATE_VHT40)
6495 {
6496 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6497 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6498 }
6499 else if (rate_flags & eHAL_TX_RATE_VHT20)
6500 {
6501 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6502 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6503 }
6504
Leo Chang6f8870f2013-03-26 18:11:36 -07006505 maxSpeedMCS = 1;
6506 if (currentRate > maxRate)
6507 {
6508 maxRate = currentRate;
6509 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306510
Leo Chang6f8870f2013-03-26 18:11:36 -07006511 }
6512 else
6513#endif /* WLAN_FEATURE_11AC */
6514 {
6515 if (rate_flags & eHAL_TX_RATE_HT40)
6516 {
6517 rateFlag |= 1;
6518 }
6519 if (rate_flags & eHAL_TX_RATE_SGI)
6520 {
6521 rateFlag |= 2;
6522 }
6523
6524 for (i = 0; i < MCSLeng; i++)
6525 {
6526 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6527 for (j = 0; j < temp; j++)
6528 {
6529 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6530 {
6531 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6532 break;
6533 }
6534 }
6535 if ((j < temp) && (currentRate > maxRate))
6536 {
6537 maxRate = currentRate;
6538 maxSpeedMCS = 1;
6539 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 }
6542 }
6543 }
6544
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306545 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6546 {
6547 maxRate = myRate;
6548 maxSpeedMCS = 1;
6549 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6550 }
6551
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006553 if (((maxRate < myRate) && (0 == rssidx)) ||
6554 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 {
6556 maxRate = myRate;
6557 if (rate_flags & eHAL_TX_RATE_LEGACY)
6558 {
6559 maxSpeedMCS = 0;
6560 }
6561 else
6562 {
6563 maxSpeedMCS = 1;
6564 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6565 }
6566 }
6567
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306568 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 {
6570 sinfo->txrate.legacy = maxRate;
6571#ifdef LINKSPEED_DEBUG_ENABLED
6572 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6573#endif //LINKSPEED_DEBUG_ENABLED
6574 }
6575 else
6576 {
6577 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006578#ifdef WLAN_FEATURE_11AC
6579 sinfo->txrate.nss = 1;
6580 if (rate_flags & eHAL_TX_RATE_VHT80)
6581 {
6582 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306583 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006584 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306585 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006586 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306587 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6588 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6589 }
6590 else if (rate_flags & eHAL_TX_RATE_VHT20)
6591 {
6592 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6593 }
6594#endif /* WLAN_FEATURE_11AC */
6595 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6596 {
6597 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6598 if (rate_flags & eHAL_TX_RATE_HT40)
6599 {
6600 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6601 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 if (rate_flags & eHAL_TX_RATE_SGI)
6604 {
6605 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6606 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306607
Jeff Johnson295189b2012-06-20 16:38:30 -07006608#ifdef LINKSPEED_DEBUG_ENABLED
6609 pr_info("Reporting MCS rate %d flags %x\n",
6610 sinfo->txrate.mcs,
6611 sinfo->txrate.flags );
6612#endif //LINKSPEED_DEBUG_ENABLED
6613 }
6614 }
6615 else
6616 {
6617 // report current rate instead of max rate
6618
6619 if (rate_flags & eHAL_TX_RATE_LEGACY)
6620 {
6621 //provide to the UI in units of 100kbps
6622 sinfo->txrate.legacy = myRate;
6623#ifdef LINKSPEED_DEBUG_ENABLED
6624 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6625#endif //LINKSPEED_DEBUG_ENABLED
6626 }
6627 else
6628 {
6629 //must be MCS
6630 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006631#ifdef WLAN_FEATURE_11AC
6632 sinfo->txrate.nss = 1;
6633 if (rate_flags & eHAL_TX_RATE_VHT80)
6634 {
6635 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6636 }
6637 else
6638#endif /* WLAN_FEATURE_11AC */
6639 {
6640 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 if (rate_flags & eHAL_TX_RATE_SGI)
6643 {
6644 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6645 }
6646 if (rate_flags & eHAL_TX_RATE_HT40)
6647 {
6648 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6649 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006650#ifdef WLAN_FEATURE_11AC
6651 else if (rate_flags & eHAL_TX_RATE_VHT80)
6652 {
6653 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6654 }
6655#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006656#ifdef LINKSPEED_DEBUG_ENABLED
6657 pr_info("Reporting actual MCS rate %d flags %x\n",
6658 sinfo->txrate.mcs,
6659 sinfo->txrate.flags );
6660#endif //LINKSPEED_DEBUG_ENABLED
6661 }
6662 }
6663 sinfo->filled |= STATION_INFO_TX_BITRATE;
6664
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006665 sinfo->tx_packets =
6666 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6667 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6668 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6669 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6670
6671 sinfo->tx_retries =
6672 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6673 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6674 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6675 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6676
6677 sinfo->tx_failed =
6678 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6679 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6680 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6681 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6682
6683 sinfo->filled |=
6684 STATION_INFO_TX_PACKETS |
6685 STATION_INFO_TX_RETRIES |
6686 STATION_INFO_TX_FAILED;
6687
6688 EXIT();
6689 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006690}
6691
6692static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6693 struct net_device *dev, bool mode, v_SINT_t timeout)
6694{
6695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306696 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306698 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699
Jeff Johnsone7245742012-09-05 17:12:55 -07006700 ENTER();
6701
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 if (NULL == pAdapter)
6703 {
6704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6705 return -ENODEV;
6706 }
6707
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306709 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306710
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306711 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306712 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6714 "%s: HDD context is not valid", __func__);
6715 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306716 }
6717
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306718 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6719 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6720 (pHddCtx->cfg_ini->fhostArpOffload) &&
6721 (eConnectionState_Associated ==
6722 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6723 {
6724 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6725 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6726 {
6727 hddLog(VOS_TRACE_LEVEL_INFO,
6728 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6729 __func__, vos_status);
6730 }
6731 }
6732
Jeff Johnson295189b2012-06-20 16:38:30 -07006733 /**The get power cmd from the supplicant gets updated by the nl only
6734 *on successful execution of the function call
6735 *we are oppositely mapped w.r.t mode in the driver
6736 **/
6737 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6738
Jeff Johnsone7245742012-09-05 17:12:55 -07006739 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 if (VOS_STATUS_E_FAILURE == vos_status)
6741 {
6742 return -EINVAL;
6743 }
6744 return 0;
6745}
6746
6747
6748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6749static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6750 struct net_device *netdev,
6751 u8 key_index)
6752{
Jeff Johnsone7245742012-09-05 17:12:55 -07006753 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 return 0;
6755}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306756#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006757
6758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6759static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6760 struct net_device *dev,
6761 struct ieee80211_txq_params *params)
6762{
Jeff Johnsone7245742012-09-05 17:12:55 -07006763 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 return 0;
6765}
6766#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6767static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6768 struct ieee80211_txq_params *params)
6769{
Jeff Johnsone7245742012-09-05 17:12:55 -07006770 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 return 0;
6772}
6773#endif //LINUX_VERSION_CODE
6774
6775static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6776 struct net_device *dev, u8 *mac)
6777{
6778 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306779 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006780 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306781 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006782 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006783
Jeff Johnsone7245742012-09-05 17:12:55 -07006784 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306785 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 return -EINVAL;
6789 }
6790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6792 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006793
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306794 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6797 "%s: HDD context is not valid", __func__);
6798 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006799 }
6800
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 )
6804 {
6805 if( NULL == mac )
6806 {
6807 v_U16_t i;
6808 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6809 {
6810 if(pAdapter->aStaInfo[i].isUsed)
6811 {
6812 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6813 hddLog(VOS_TRACE_LEVEL_INFO,
6814 "%s: Delete STA with MAC::"
6815 "%02x:%02x:%02x:%02x:%02x:%02x",
6816 __func__,
6817 macAddr[0], macAddr[1], macAddr[2],
6818 macAddr[3], macAddr[4], macAddr[5]);
6819 hdd_softap_sta_deauth(pAdapter, macAddr);
6820 }
6821 }
6822 }
6823 else
6824 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006825
6826 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6827 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6828 {
6829 hddLog(VOS_TRACE_LEVEL_INFO,
6830 "%s: Skip this DEL STA as this is not used::"
6831 "%02x:%02x:%02x:%02x:%02x:%02x",
6832 __func__,
6833 mac[0], mac[1], mac[2],
6834 mac[3], mac[4], mac[5]);
6835 return -ENOENT;
6836 }
6837
6838 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_INFO,
6841 "%s: Skip this DEL STA as deauth is in progress::"
6842 "%02x:%02x:%02x:%02x:%02x:%02x",
6843 __func__,
6844 mac[0], mac[1], mac[2],
6845 mac[3], mac[4], mac[5]);
6846 return -ENOENT;
6847 }
6848
6849 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6850
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 hddLog(VOS_TRACE_LEVEL_INFO,
6852 "%s: Delete STA with MAC::"
6853 "%02x:%02x:%02x:%02x:%02x:%02x",
6854 __func__,
6855 mac[0], mac[1], mac[2],
6856 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006857
6858 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6859 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6860 {
6861 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6862 hddLog(VOS_TRACE_LEVEL_INFO,
6863 "%s: STA removal failed for ::"
6864 "%02x:%02x:%02x:%02x:%02x:%02x",
6865 __func__,
6866 mac[0], mac[1], mac[2],
6867 mac[3], mac[4], mac[5]);
6868 return -ENOENT;
6869 }
6870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 }
6872 }
6873
6874 EXIT();
6875
6876 return 0;
6877}
6878
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006879static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6880 struct net_device *dev, u8 *mac, struct station_parameters *params)
6881{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006882 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006883#ifdef FEATURE_WLAN_TDLS
6884 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006885 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006886 mask = params->sta_flags_mask;
6887
6888 set = params->sta_flags_set;
6889
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006890#ifdef WLAN_FEATURE_TDLS_DEBUG
6891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6892 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6893 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6894#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006895
6896 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6897 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006898 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006899 }
6900 }
6901#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006902 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006903}
6904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006905
6906#ifdef FEATURE_WLAN_LFR
6907static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006908 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006909{
6910#define MAX_PMKSAIDS_IN_CACHE 8
6911 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306912 static tANI_U32 i; // HDD Local Cache index
6913 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6915 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306916 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306917 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006918 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306919 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920
Jeff Johnsone7245742012-09-05 17:12:55 -07006921 ENTER();
6922
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306923 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306924 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006925 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006927 return -EINVAL;
6928 }
6929
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306930 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6931 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006932
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306933 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006934 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6936 "%s: HDD context is not valid", __func__);
6937 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 }
6939
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006941 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6942
6943 for (j = 0; j < i; j++)
6944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306945 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946 pmksa->bssid, WNI_CFG_BSSID_LEN))
6947 {
6948 /* BSSID matched previous entry. Overwrite it. */
6949 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006951 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306952 vos_mem_copy(PMKIDCache[j].PMKID,
6953 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006954 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306955 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006956 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957 dump_bssid(pmksa->bssid);
6958 dump_pmkid(halHandle, pmksa->pmkid);
6959 break;
6960 }
6961 }
6962
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006963 /* Check we compared all entries,if then take the first slot now */
6964 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6965
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006966 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306967 {
6968 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6969 vos_mem_copy(PMKIDCache[i].BSSID,
6970 pmksa->bssid, ETHER_ADDR_LEN);
6971 vos_mem_copy(PMKIDCache[i].PMKID,
6972 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006973 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006975 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006976 dump_bssid(pmksa->bssid);
6977 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306978 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006979 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306980 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006981 }
6982
6983
6984 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306985 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006986 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306987 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006988 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006989 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306990 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6991 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992 i );
6993 return 0;
6994}
6995
6996
6997static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006998 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006999{
Jeff Johnsone7245742012-09-05 17:12:55 -07007000 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001 // TODO: Implement this later.
7002 return 0;
7003}
7004
7005static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7006{
Jeff Johnsone7245742012-09-05 17:12:55 -07007007 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007008 // TODO: Implement this later.
7009 return 0;
7010}
7011#endif
7012
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007013#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307014static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007015 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7016{
7017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7018 hdd_station_ctx_t *pHddStaCtx;
7019
7020 if (NULL == pAdapter)
7021 {
7022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7023 return -ENODEV;
7024 }
7025
7026 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7027
7028 // Added for debug on reception of Re-assoc Req.
7029 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307031 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007032 ftie->ie_len);
7033 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7034 }
7035
7036#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307037 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007038 ftie->ie_len);
7039#endif
7040
7041 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307042 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7043 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007044 ftie->ie_len);
7045 return 0;
7046}
7047#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007048
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307049#ifdef FEATURE_WLAN_SCAN_PNO
7050
7051void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7052 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7053{
7054 int ret;
7055 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7056 hdd_context_t *pHddCtx;
7057
7058 if (NULL == pAdapter)
7059 {
7060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7061 "%s: HDD adapter is Null", __func__);
7062 return ;
7063 }
7064
7065 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7066 if (NULL == pHddCtx)
7067 {
7068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7069 "%s: HDD context is Null!!!", __func__);
7070 return ;
7071 }
7072
7073 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7074
7075 if (0 > ret)
7076 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7077
7078 cfg80211_sched_scan_results(pHddCtx->wiphy);
7079}
7080
7081/*
7082 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7083 * NL interface to enable PNO
7084 */
7085static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7086 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7087{
7088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7089 tpSirPNOScanReq pPnoRequest = NULL;
7090 hdd_context_t *pHddCtx;
7091 tHalHandle hHal;
7092 v_U32_t i, indx, num_ch;
7093 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7094 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7095 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7096 eHalStatus status = eHAL_STATUS_FAILURE;
7097
7098 if (NULL == pAdapter)
7099 {
7100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7101 "%s: HDD adapter is Null", __func__);
7102 return -ENODEV;
7103 }
7104
7105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7106 if (NULL == pHddCtx)
7107 {
7108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7109 "%s: HDD context is Null!!!", __func__);
7110 return -ENODEV;
7111 }
7112
7113 if (pHddCtx->isLogpInProgress)
7114 {
7115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7116 "%s: LOGP in Progress. Ignore!!!", __func__);
7117 return -EAGAIN;
7118 }
7119
7120 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7121 if (NULL == hHal)
7122 {
7123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7124 "%s: HAL context is Null!!!", __func__);
7125 return -EAGAIN;
7126 }
7127
7128 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7129 if (NULL == pPnoRequest)
7130 {
7131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7132 "%s: vos_mem_malloc failed", __func__);
7133 return -ENODEV;
7134 }
7135
7136 pPnoRequest->enable = 1; /*Enable PNO */
7137 pPnoRequest->ucNetworksCount = request->n_match_sets;
7138
7139 if (( !pPnoRequest->ucNetworksCount ) ||
7140 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7141 {
7142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7143 "Network input is not correct");
7144 goto error;
7145 }
7146
7147 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7148 {
7149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7150 "Incorrect number of channels");
7151 goto error;
7152 }
7153
7154 /* Framework provides one set of channels(all)
7155 * common for all saved profile */
7156 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7157 channels_allowed, &num_channels_allowed))
7158 {
7159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7160 "%s: failed to get valid channel list", __func__);
7161 goto error;
7162 }
7163 /* Checking each channel against allowed channel list */
7164 num_ch = 0;
7165 for (i = 0; i < request->n_channels; i++)
7166 {
7167 for (indx = 0; indx < num_channels_allowed; indx++)
7168 {
7169 if (request->channels[i]->hw_value == channels_allowed[indx])
7170 {
7171 valid_ch[num_ch++] = request->channels[i]->hw_value;
7172 break ;
7173 }
7174 }
7175 }
7176
7177 /* Filling per profile params */
7178 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7179 {
7180 pPnoRequest->aNetworks[i].ssId.length =
7181 request->match_sets[i].ssid.ssid_len;
7182
7183 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7184 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7185 {
7186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7187 "SSID Len %d is not correct for network %d",
7188 pPnoRequest->aNetworks[i].ssId.length, i);
7189 goto error;
7190 }
7191
7192 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7193 request->match_sets[i].ssid.ssid,
7194 request->match_sets[i].ssid.ssid_len);
7195 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7196 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7197 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7198
7199 /*Copying list of valid channel into request */
7200 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7201 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7202
7203 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7204 }
7205
7206 /* framework provides interval in ms */
7207 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7208 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7209 (request->interval)/1000;
7210 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7211 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7212
7213 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7214 pPnoRequest, pAdapter->sessionId,
7215 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7216 if (eHAL_STATUS_SUCCESS != status)
7217 {
7218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7219 "Failed to enable PNO");
7220 goto error;
7221 }
7222
7223error:
7224 vos_mem_free(pPnoRequest);
7225 return status;
7226}
7227
7228/*
7229 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7230 * NL interface to disable PNO
7231 */
7232static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7233 struct net_device *dev)
7234{
7235 eHalStatus status = eHAL_STATUS_FAILURE;
7236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7237 hdd_context_t *pHddCtx;
7238 tHalHandle hHal;
7239 tpSirPNOScanReq pPnoRequest = NULL;
7240
7241 ENTER();
7242
7243 if (NULL == pAdapter)
7244 {
7245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7246 "%s: HDD adapter is Null", __func__);
7247 return -ENODEV;
7248 }
7249
7250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7251 if (NULL == pHddCtx)
7252 {
7253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7254 "%s: HDD context is Null!!!", __func__);
7255 return -ENODEV;
7256 }
7257
7258 if (pHddCtx->isLogpInProgress)
7259 {
7260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7261 "%s: LOGP in Progress. Ignore!!!", __func__);
7262 return -EAGAIN;
7263 }
7264
7265 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7266 if (NULL == hHal)
7267 {
7268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7269 "%s: HAL context is Null!!!", __func__);
7270 return -EAGAIN;
7271 }
7272
7273 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7274 if (NULL == pPnoRequest)
7275 {
7276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7277 "%s: vos_mem_malloc failed", __func__);
7278 return -ENODEV;
7279 }
7280
7281 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7282 pPnoRequest->enable = 0; /* Disable PNO */
7283 pPnoRequest->ucNetworksCount = 0;
7284
7285 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7286 pAdapter->sessionId,
7287 NULL, pAdapter);
7288 if (eHAL_STATUS_SUCCESS != status)
7289 {
7290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7291 "Failed to disabled PNO");
7292 }
7293
7294 vos_mem_free(pPnoRequest);
7295
7296 EXIT();
7297 return status;
7298}
7299
7300#endif /*FEATURE_WLAN_SCAN_PNO*/
7301
7302
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007303#ifdef FEATURE_WLAN_TDLS
7304static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7305 u8 *peer, u8 action_code, u8 dialog_token,
7306 u16 status_code, const u8 *buf, size_t len)
7307{
7308
7309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7310 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007311 u8 peerMac[6];
7312 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007313 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007314 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007315 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007316
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007317 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007320 "Invalid arguments");
7321 return -EINVAL;
7322 }
7323
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007324 if (pHddCtx->isLogpInProgress)
7325 {
7326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007328 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007329 return -EBUSY;
7330 }
7331
Hoonki Lee27511902013-03-14 18:19:06 -07007332 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007333 {
Hoonki Lee27511902013-03-14 18:19:06 -07007334 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7335 "%s: TDLS mode is disabled OR not enabled in FW."
7336 MAC_ADDRESS_STR " action %d declined.",
7337 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007338 return -ENOTSUPP;
7339 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007340
Hoonki Lee27511902013-03-14 18:19:06 -07007341 /* other than teardown frame, other mgmt frames are not sent if disabled */
7342 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7343 {
7344 /* if tdls_mode is disabled to respond to peer's request */
7345 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7346 {
7347 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7348 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007349 " TDLS mode is disabled. action %d declined.",
7350 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007351
7352 return -ENOTSUPP;
7353 }
7354 }
7355
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007356 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7357 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007358 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007359 {
7360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007361 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007362 " TDLS setup is ongoing. action %d declined.",
7363 __func__, MAC_ADDR_ARRAY(peer), action_code);
7364 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007365 }
7366 }
7367
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007368 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7369 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007370 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007371 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007372 {
7373 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7374 we return error code at 'add_station()'. Hence we have this
7375 check again in addtion to add_station().
7376 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007377 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007378 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007381 " TDLS Max peer already connected. action %d declined.",
7382 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007383 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007384 }
7385 else
7386 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007387 /* maximum reached. tweak to send error code to peer and return
7388 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007389 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7391 "%s: " MAC_ADDRESS_STR
7392 " TDLS Max peer already connected send response status %d",
7393 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007394 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007395 /* fall through to send setup resp with failure status
7396 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007397 }
7398 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007399 else
7400 {
7401 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007402 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007403 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007404 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007406 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7407 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007408 return -EPERM;
7409 }
7410 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007411 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007412 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007413
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007414#ifdef WLAN_FEATURE_TDLS_DEBUG
7415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007416 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7417 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7418 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007419#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007420
Hoonki Leea34dd892013-02-05 22:56:02 -08007421 /*Except teardown responder will not be used so just make 0*/
7422 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007423 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007424 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007425
7426 hddTdlsPeer_t *pTdlsPeer;
7427 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7428
7429 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7430 responder = pTdlsPeer->is_responder;
7431 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007432 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7434 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7435 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7436 dialog_token, status_code, len);
7437 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007438 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007439 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007440
Hoonki Lee14621352013-04-16 17:51:19 -07007441 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7442 (SIR_MAC_TDLS_DIS_RSP == action_code))
7443 {
7444 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7445 {
7446 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7447 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7448 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7449 }
7450 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7451 }
7452
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007453 /* make sure doesn't call send_mgmt() while it is pending */
7454 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7455 {
7456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7457 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7458 __func__, MAC_ADDR_ARRAY(peer), action_code);
7459 return -EBUSY;
7460 }
7461
7462 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007463 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7464
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007465 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007466 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007467
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007468 if (VOS_STATUS_SUCCESS != status)
7469 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7471 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007472 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007473 wlan_hdd_tdls_check_bmps(pAdapter);
7474 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007475 }
7476
Hoonki Leed37cbb32013-04-20 00:31:14 -07007477 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7478 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7479
7480 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007481 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7483 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7484 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007485 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007486 wlan_hdd_tdls_check_bmps(pAdapter);
7487 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007488 }
7489
Gopichand Nakkala05922802013-03-14 12:23:19 -07007490 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007491 {
7492 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007493 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007494 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007495
Hoonki Leea34dd892013-02-05 22:56:02 -08007496 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7497 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007498 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007499 }
7500 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7501 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007502 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007503 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007504
7505 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007506error:
7507 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7508 because we already know that this transaction will be failed,
7509 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7510 to be safe, do not change the state mahine.
7511 */
7512 if(max_sta_failed == 0 &&
7513 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7514 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7515 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007516}
7517
7518static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7519 u8 *peer, enum nl80211_tdls_operation oper)
7520{
7521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307523 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307524#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7525 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307526 tANI_U8 staIdx;
7527#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007528#ifdef WLAN_FEATURE_TDLS_DEBUG
7529 const char *tdls_oper_str[]= {
7530 "NL80211_TDLS_DISCOVERY_REQ",
7531 "NL80211_TDLS_SETUP",
7532 "NL80211_TDLS_TEARDOWN",
7533 "NL80211_TDLS_ENABLE_LINK",
7534 "NL80211_TDLS_DISABLE_LINK",
7535 "NL80211_TDLS_UNKONW_OPER"};
7536#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007537 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007538
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007540 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007542 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007543 return -EINVAL;
7544 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307546 status = wlan_hdd_validate_context(pHddCtx);
7547
7548 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007549 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7551 "%s: HDD context is not valid", __func__);
7552 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007553 }
7554
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007555 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7556
7557 if ( NULL == pTdlsPeer ) {
7558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7559 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7560 return -EINVAL;
7561 }
7562
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007563#ifdef WLAN_FEATURE_TDLS_DEBUG
7564 if((int)oper > 4)
7565 oper = 5;
7566
7567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007568 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7569 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007570 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007571#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007572
7573 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007574 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007575 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007577 "TDLS Disabled in INI OR not enabled in FW. "
7578 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007579 return -ENOTSUPP;
7580 }
7581
7582 switch (oper) {
7583 case NL80211_TDLS_ENABLE_LINK:
7584 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007585 VOS_STATUS status;
7586
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007587 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7588 {
7589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7590 MAC_ADDRESS_STR " failed",
7591 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7592 return -EINVAL;
7593 }
7594
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007595 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007596 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007597 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007598 /* start TDLS client registration with TL */
7599 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007600 if (VOS_STATUS_SUCCESS == status)
7601 {
Hoonki Lee14621352013-04-16 17:51:19 -07007602 if (pTdlsPeer->is_responder == 0)
7603 {
7604 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7605
7606 wlan_hdd_tdls_timer_restart(pAdapter,
7607 &pTdlsPeer->initiatorWaitTimeoutTimer,
7608 WAIT_TIME_TDLS_INITIATOR);
7609 /* suspend initiator TX until it receives direct packet from the
7610 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7611 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7612 &staId, NULL);
7613 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007614 wlan_hdd_tdls_increment_peer_count(pAdapter);
7615 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007616 wlan_hdd_tdls_check_bmps(pAdapter);
7617 }
7618
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007619 }
7620 break;
7621 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007622 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007623 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007624 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007625 long status;
7626
7627 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7628
Lee Hoonkic1262f22013-01-24 21:59:00 -08007629 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7630 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007631
7632 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7633 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7634 if (status <= 0)
7635 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007636 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7638 "%s: Del station failed status %ld",
7639 __func__, status);
7640 return -EPERM;
7641 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007642 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007643 }
7644 else
7645 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7647 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007648 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307649#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7650 if (pHddTdlsCtx->defer_link_lost_indication)
7651 {
7652 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7653 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7654 {
7655 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7656 if ( 0 != status)
7657 {
7658 hddLog(VOS_TRACE_LEVEL_ERROR,
7659 "%s wlan_hdd_disconnect failure, returned %d \n",
7660 __func__, (int)status );
7661 return -EINVAL;
7662 }
7663 }
7664 }
7665#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007666 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007667 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007668 case NL80211_TDLS_TEARDOWN:
7669 case NL80211_TDLS_SETUP:
7670 case NL80211_TDLS_DISCOVERY_REQ:
7671 /* We don't support in-driver setup/teardown/discovery */
7672 return -ENOTSUPP;
7673 default:
7674 return -ENOTSUPP;
7675 }
7676 return 0;
7677}
Chilam NG571c65a2013-01-19 12:27:36 +05307678
7679int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7680 struct net_device *dev, u8 *peer)
7681{
7682 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7683 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7684
7685 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7686 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7687}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007688#endif
7689
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307690#ifdef WLAN_FEATURE_GTK_OFFLOAD
7691/*
7692 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7693 * Callback rountine called upon receiving response for
7694 * get offload info
7695 */
7696void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7697 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7698{
7699
7700 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7701
7702 ENTER();
7703
7704 if (NULL == pAdapter)
7705 {
7706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7707 "%s: HDD adapter is Null", __func__);
7708 return ;
7709 }
7710
7711 if (NULL == pGtkOffloadGetInfoRsp)
7712 {
7713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7714 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7715 return ;
7716 }
7717
7718 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7719 {
7720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7721 "%s: wlan Failed to get replay counter value",
7722 __func__);
7723 return ;
7724 }
7725
7726 /* Update replay counter to NL */
7727 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7728 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7729}
7730
7731/*
7732 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7733 * This function is used to offload GTK rekeying job to the firmware.
7734 */
7735int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7736 struct cfg80211_gtk_rekey_data *data)
7737{
7738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7739 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7740 hdd_station_ctx_t *pHddStaCtx;
7741 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307742 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307743 tpSirGtkOffloadParams pGtkOffloadReqParams;
7744 eHalStatus status = eHAL_STATUS_FAILURE;
7745
7746 ENTER();
7747
7748 if (NULL == pAdapter)
7749 {
7750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7751 "%s: HDD adapter is Null", __func__);
7752 return -ENODEV;
7753 }
7754
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307755 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307756
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307757 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307758 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7760 "%s: HDD context is not valid", __func__);
7761 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307762 }
7763
7764 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7765 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7766 if (NULL == hHal)
7767 {
7768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7769 "%s: HAL context is Null!!!", __func__);
7770 return -EAGAIN;
7771 }
7772
7773 pGtkOffloadReqParams =
7774 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7775
7776 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7777 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7778 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7779 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7780 WNI_CFG_BSSID_LEN);
7781 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7782 sizeof (tANI_U64));
7783
7784 if (TRUE == pHddCtx->hdd_wlan_suspended)
7785 {
7786 /* if wlan is suspended, enable GTK offload directly from here */
7787 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7788 pAdapter->sessionId);
7789
7790 if (eHAL_STATUS_SUCCESS != status)
7791 {
7792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7793 "%s: sme_SetGTKOffload failed, returned %d",
7794 __func__, status);
7795 return status;
7796 }
7797 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7799 "%s: sme_SetGTKOffload successfull", __func__);
7800 }
7801 else
7802 {
7803 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7805 "%s: wlan not suspended GTKOffload request is stored",
7806 __func__);
7807 return eHAL_STATUS_SUCCESS;
7808 }
7809 return status;
7810}
7811#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307814static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007815{
7816 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7817 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7818 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7819 .change_station = wlan_hdd_change_station,
7820#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7821 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7822 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7823 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007824#else
7825 .start_ap = wlan_hdd_cfg80211_start_ap,
7826 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7827 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007828#endif
7829 .change_bss = wlan_hdd_cfg80211_change_bss,
7830 .add_key = wlan_hdd_cfg80211_add_key,
7831 .get_key = wlan_hdd_cfg80211_get_key,
7832 .del_key = wlan_hdd_cfg80211_del_key,
7833 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007834#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 .scan = wlan_hdd_cfg80211_scan,
7838 .connect = wlan_hdd_cfg80211_connect,
7839 .disconnect = wlan_hdd_cfg80211_disconnect,
7840 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7841 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7842 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7843 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7844 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7846 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7847 .mgmt_tx = wlan_hdd_action,
7848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7849 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7850 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7851 .set_txq_params = wlan_hdd_set_txq_params,
7852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 .get_station = wlan_hdd_cfg80211_get_station,
7854 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7855 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007856 .add_station = wlan_hdd_cfg80211_add_station,
7857#ifdef FEATURE_WLAN_LFR
7858 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7859 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7860 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7861#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007862#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7863 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7864#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007865#ifdef FEATURE_WLAN_TDLS
7866 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7867 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7868#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307869#ifdef WLAN_FEATURE_GTK_OFFLOAD
7870 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7871#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307872#ifdef FEATURE_WLAN_SCAN_PNO
7873 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
7874 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
7875#endif /*FEATURE_WLAN_SCAN_PNO */
Jeff Johnson295189b2012-06-20 16:38:30 -07007876};
7877