blob: 65e5efd2d79f2ba0aa227c9fcef13411cdd9d944 [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
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530656 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
657
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530659 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700660 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 | BIT(NL80211_IFTYPE_P2P_CLIENT)
662 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 | BIT(NL80211_IFTYPE_AP);
664
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800666 if( pCfg->enableMCC )
667 {
668 /* Currently, supports up to two channels */
669 wlan_hdd_iface_combination.num_different_channels = 2;
670
671 if( !pCfg->allowMCCGODiffBI )
672 wlan_hdd_iface_combination.beacon_int_infra_match = true;
673
674 }
675 wiphy->iface_combinations = &wlan_hdd_iface_combination;
676 wiphy->n_iface_combinations = 1;
677#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800678
Jeff Johnson295189b2012-06-20 16:38:30 -0700679 /* Before registering we need to update the ht capabilitied based
680 * on ini values*/
681 if( !pCfg->ShortGI20MhzEnable )
682 {
683 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
684 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
685 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
686 }
687
688 if( !pCfg->ShortGI40MhzEnable )
689 {
690 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
691 }
692
693 if( !pCfg->nChannelBondingMode5GHz )
694 {
695 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
696 }
697
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530698 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
699 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
700
701 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
702 {
703
704 if (NULL == wiphy->bands[i])
705 {
706 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
707 __func__, i);
708 continue;
709 }
710
711 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
712 {
713 struct ieee80211_supported_band *band = wiphy->bands[i];
714
715 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
716 {
717 // Enable social channels for P2P
718 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
719 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
720 else
721 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
722 continue;
723 }
724 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
725 {
726 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
727 continue;
728 }
729 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 }
731 /*Initialise the supported cipher suite details*/
732 wiphy->cipher_suites = hdd_cipher_suites;
733 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
734
735 /*signal strength in mBm (100*dBm) */
736 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
737
738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 wiphy->max_remain_on_channel_duration = 1000;
740#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700741
742 /* Register our wiphy dev with cfg80211 */
743 if (0 > wiphy_register(wiphy))
744 {
745 /* print eror */
746 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
747 return -EIO;
748 }
749
750 EXIT();
751 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530752}
Jeff Johnson295189b2012-06-20 16:38:30 -0700753
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700754/* In this function we will try to get default country code from crda.
755 If the gCrdaDefaultCountryCode is configured in ini file,
756 we will try to call user space crda to get the regulatory settings for
757 that country. We will timeout if we can't get it from crda.
758 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
759*/
760int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
761{
762 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
763 if (memcmp(pCfg->crdaDefaultCountryCode,
764 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
765 {
766 init_completion(&pHddCtx->driver_crda_req);
767 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
768 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
769 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700770 /* if the country is not found from current regulatory.bin,
771 fall back to world domain */
772 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
773 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700774 }
775 return 0;
776}
777
Jeff Johnson295189b2012-06-20 16:38:30 -0700778/* In this function we will do all post VOS start initialization.
779 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530780 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700781*/
782void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
783{
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
785 /* Register for all P2P action, public action etc frames */
786 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
787
Jeff Johnsone7245742012-09-05 17:12:55 -0700788 ENTER();
789
Jeff Johnson295189b2012-06-20 16:38:30 -0700790 /* Right now we are registering these frame when driver is getting
791 initialized. Once we will move to 2.6.37 kernel, in which we have
792 frame register ops, we will move this code as a part of that */
793 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530794 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
796
797 /* GAS Initial Response */
798 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
799 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530800
Jeff Johnson295189b2012-06-20 16:38:30 -0700801 /* GAS Comeback Request */
802 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
803 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
804
805 /* GAS Comeback Response */
806 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
807 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
808
809 /* P2P Public Action */
810 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530811 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700812 P2P_PUBLIC_ACTION_FRAME_SIZE );
813
814 /* P2P Action */
815 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
816 (v_U8_t*)P2P_ACTION_FRAME,
817 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700818
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530819 /* WNM BSS Transition Request frame */
820 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
821 (v_U8_t*)WNM_BSS_ACTION_FRAME,
822 WNM_BSS_ACTION_FRAME_SIZE );
823
Chet Lanctot186b5732013-03-18 10:26:30 -0700824#ifdef WLAN_FEATURE_11W
825 /* SA Query Response Action Frame */
826 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
827 (v_U8_t*)SA_QUERY_FRAME_RSP,
828 SA_QUERY_FRAME_RSP_SIZE );
829#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700830}
831
832void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
833{
Jeff Johnson295189b2012-06-20 16:38:30 -0700834 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
835 /* Register for all P2P action, public action etc frames */
836 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
837
Jeff Johnsone7245742012-09-05 17:12:55 -0700838 ENTER();
839
Jeff Johnson295189b2012-06-20 16:38:30 -0700840 /* Right now we are registering these frame when driver is getting
841 initialized. Once we will move to 2.6.37 kernel, in which we have
842 frame register ops, we will move this code as a part of that */
843 /* GAS Initial Request */
844
845 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
846 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
847
848 /* GAS Initial Response */
849 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
850 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530851
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 /* GAS Comeback Request */
853 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
854 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
855
856 /* GAS Comeback Response */
857 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
858 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
859
860 /* P2P Public Action */
861 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530862 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700863 P2P_PUBLIC_ACTION_FRAME_SIZE );
864
865 /* P2P Action */
866 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
867 (v_U8_t*)P2P_ACTION_FRAME,
868 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700869
870#ifdef WLAN_FEATURE_11W
871 /* SA Query Response Action Frame */
872 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
873 (v_U8_t*)SA_QUERY_FRAME_RSP,
874 SA_QUERY_FRAME_RSP_SIZE );
875#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700876}
877
878#ifdef FEATURE_WLAN_WAPI
879void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
880 const u8 *mac_addr, u8 *key , int key_Len)
881{
882 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
883 tCsrRoamSetKey setKey;
884 v_BOOL_t isConnected = TRUE;
885 int status = 0;
886 v_U32_t roamId= 0xFF;
887 tANI_U8 *pKeyPtr = NULL;
888 int n = 0;
889
890 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
891 __func__,pAdapter->device_mode);
892
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530893 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700894 setKey.keyId = key_index; // Store Key ID
895 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
896 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
897 setKey.paeRole = 0 ; // the PAE role
898 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
899 {
900 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
901 }
902 else
903 {
904 isConnected = hdd_connIsConnected(pHddStaCtx);
905 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
906 }
907 setKey.keyLength = key_Len;
908 pKeyPtr = setKey.Key;
909 memcpy( pKeyPtr, key, key_Len);
910
911 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
912 __func__, key_Len);
913 for (n = 0 ; n < key_Len; n++)
914 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
915 __func__,n,setKey.Key[n]);
916
917 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
918 if ( isConnected )
919 {
920 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
921 pAdapter->sessionId, &setKey, &roamId );
922 }
923 if ( status != 0 )
924 {
925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
926 "[%4d] sme_RoamSetKey returned ERROR status= %d",
927 __LINE__, status );
928 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
929 }
930}
931#endif /* FEATURE_WLAN_WAPI*/
932
933#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530934int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 beacon_data_t **ppBeacon,
936 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700937#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530938int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700939 beacon_data_t **ppBeacon,
940 struct cfg80211_beacon_data *params,
941 int dtim_period)
942#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530943{
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 int size;
945 beacon_data_t *beacon = NULL;
946 beacon_data_t *old = NULL;
947 int head_len,tail_len;
948
Jeff Johnsone7245742012-09-05 17:12:55 -0700949 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 if (params->head && !params->head_len)
951 return -EINVAL;
952
953 old = pAdapter->sessionCtx.ap.beacon;
954
955 if (!params->head && !old)
956 return -EINVAL;
957
958 if (params->tail && !params->tail_len)
959 return -EINVAL;
960
961#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
962 /* Kernel 3.0 is not updating dtim_period for set beacon */
963 if (!params->dtim_period)
964 return -EINVAL;
965#endif
966
967 if(params->head)
968 head_len = params->head_len;
969 else
970 head_len = old->head_len;
971
972 if(params->tail || !old)
973 tail_len = params->tail_len;
974 else
975 tail_len = old->tail_len;
976
977 size = sizeof(beacon_data_t) + head_len + tail_len;
978
979 beacon = kzalloc(size, GFP_KERNEL);
980
981 if( beacon == NULL )
982 return -ENOMEM;
983
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700984#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 if(params->dtim_period || !old )
986 beacon->dtim_period = params->dtim_period;
987 else
988 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700989#else
990 if(dtim_period || !old )
991 beacon->dtim_period = dtim_period;
992 else
993 beacon->dtim_period = old->dtim_period;
994#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530995
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
997 beacon->tail = beacon->head + head_len;
998 beacon->head_len = head_len;
999 beacon->tail_len = tail_len;
1000
1001 if(params->head) {
1002 memcpy (beacon->head,params->head,beacon->head_len);
1003 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301004 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 if(old)
1006 memcpy (beacon->head,old->head,beacon->head_len);
1007 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301008
Jeff Johnson295189b2012-06-20 16:38:30 -07001009 if(params->tail) {
1010 memcpy (beacon->tail,params->tail,beacon->tail_len);
1011 }
1012 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301013 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 memcpy (beacon->tail,old->tail,beacon->tail_len);
1015 }
1016
1017 *ppBeacon = beacon;
1018
1019 kfree(old);
1020
1021 return 0;
1022
1023}
Jeff Johnson295189b2012-06-20 16:38:30 -07001024
1025v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1026{
1027 int left = length;
1028 v_U8_t *ptr = pIes;
1029 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301030
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301032 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001033 elem_id = ptr[0];
1034 elem_len = ptr[1];
1035 left -= 2;
1036 if(elem_len > left)
1037 {
1038 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001039 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 eid,elem_len,left);
1041 return NULL;
1042 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301043 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 {
1045 return ptr;
1046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301047
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 left -= elem_len;
1049 ptr += (elem_len + 2);
1050 }
1051 return NULL;
1052}
1053
Jeff Johnson295189b2012-06-20 16:38:30 -07001054/* Check if rate is 11g rate or not */
1055static int wlan_hdd_rate_is_11g(u8 rate)
1056{
1057 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
1058 u8 i;
1059 for (i = 0; i < 8; i++)
1060 {
1061 if(rate == gRateArray[i])
1062 return TRUE;
1063 }
1064 return FALSE;
1065}
1066
1067/* Check for 11g rate and set proper 11g only mode */
1068static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1069 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1070{
1071 u8 i, num_rates = pIe[0];
1072
1073 pIe += 1;
1074 for ( i = 0; i < num_rates; i++)
1075 {
1076 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1077 {
1078 /* If rate set have 11g rate than change the mode to 11G */
1079 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1080 if (pIe[i] & BASIC_RATE_MASK)
1081 {
1082 /* If we have 11g rate as basic rate, it means mode
1083 is 11g only mode.
1084 */
1085 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1086 *pCheckRatesfor11g = FALSE;
1087 }
1088 }
1089 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1090 {
1091 *require_ht = TRUE;
1092 }
1093 }
1094 return;
1095}
1096
1097static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1098{
1099 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1100 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1101 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1102 u8 checkRatesfor11g = TRUE;
1103 u8 require_ht = FALSE;
1104 u8 *pIe=NULL;
1105
1106 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1107
1108 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1109 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1110 if (pIe != NULL)
1111 {
1112 pIe += 1;
1113 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1114 &pConfig->SapHw_mode);
1115 }
1116
1117 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1118 WLAN_EID_EXT_SUPP_RATES);
1119 if (pIe != NULL)
1120 {
1121
1122 pIe += 1;
1123 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1124 &pConfig->SapHw_mode);
1125 }
1126
1127 if( pConfig->channel > 14 )
1128 {
1129 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1130 }
1131
1132 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1133 WLAN_EID_HT_CAPABILITY);
1134
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301135 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 {
1137 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1138 if(require_ht)
1139 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1140 }
1141}
1142
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301143static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1144 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1145{
1146 v_U8_t ielen = 0;
1147 v_U8_t *pIe = NULL;
1148 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1149
1150 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1151 pBeacon->tail, pBeacon->tail_len);
1152
1153 if (pIe)
1154 {
1155 ielen = pIe[1] + 2;
1156 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1157 {
1158 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1159 }
1160 else
1161 {
1162 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1163 return -EINVAL;
1164 }
1165 *total_ielen += ielen;
1166 }
1167 return 0;
1168}
1169
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001171static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1172 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001173#else
1174static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1175 struct cfg80211_beacon_data *params)
1176#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001177{
1178 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301179 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001180 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001181 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001182
1183 genie = vos_mem_malloc(MAX_GENIE_LEN);
1184
1185 if(genie == NULL) {
1186
1187 return -ENOMEM;
1188 }
1189
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301190 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1191 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301193 ret = -EINVAL;
1194 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 }
1196
1197#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301198 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1199 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1200 {
1201 ret = -EINVAL;
1202 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 }
1204#endif
1205
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301206 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1207 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301209 ret = -EINVAL;
1210 goto done;
1211 }
1212
1213 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1214 {
1215 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1216 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301218 ret = -EINVAL;
1219 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001220 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001222
1223 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1224 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1225 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1226 {
1227 hddLog(LOGE,
1228 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001229 ret = -EINVAL;
1230 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 }
1232
1233 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1234 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1235 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1236 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1237 ==eHAL_STATUS_FAILURE)
1238 {
1239 hddLog(LOGE,
1240 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001241 ret = -EINVAL;
1242 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001243 }
1244
1245 // Added for ProResp IE
1246 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1247 {
1248 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1249 u8 probe_rsp_ie_len[3] = {0};
1250 u8 counter = 0;
1251 /* Check Probe Resp Length if it is greater then 255 then Store
1252 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1253 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1254 Store More then 255 bytes into One Variable.
1255 */
1256 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1257 {
1258 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1259 {
1260 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1261 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1262 }
1263 else
1264 {
1265 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1266 rem_probe_resp_ie_len = 0;
1267 }
1268 }
1269
1270 rem_probe_resp_ie_len = 0;
1271
1272 if (probe_rsp_ie_len[0] > 0)
1273 {
1274 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1275 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1276 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1277 probe_rsp_ie_len[0], NULL,
1278 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1279 {
1280 hddLog(LOGE,
1281 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001282 ret = -EINVAL;
1283 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001284 }
1285 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1286 }
1287
1288 if (probe_rsp_ie_len[1] > 0)
1289 {
1290 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1291 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1292 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1293 probe_rsp_ie_len[1], NULL,
1294 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1295 {
1296 hddLog(LOGE,
1297 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001298 ret = -EINVAL;
1299 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 }
1301 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1302 }
1303
1304 if (probe_rsp_ie_len[2] > 0)
1305 {
1306 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1307 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1308 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1309 probe_rsp_ie_len[2], NULL,
1310 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1311 {
1312 hddLog(LOGE,
1313 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001314 ret = -EINVAL;
1315 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001316 }
1317 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1318 }
1319
1320 if (probe_rsp_ie_len[1] == 0 )
1321 {
1322 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1323 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1324 eANI_BOOLEAN_FALSE) )
1325 {
1326 hddLog(LOGE,
1327 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1328 }
1329 }
1330
1331 if (probe_rsp_ie_len[2] == 0 )
1332 {
1333 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1334 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1335 eANI_BOOLEAN_FALSE) )
1336 {
1337 hddLog(LOGE,
1338 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1339 }
1340 }
1341
1342 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1343 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1344 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1345 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1346 == eHAL_STATUS_FAILURE)
1347 {
1348 hddLog(LOGE,
1349 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001350 ret = -EINVAL;
1351 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 }
1353 }
1354 else
1355 {
1356 // Reset WNI_CFG_PROBE_RSP Flags
1357 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1358
1359 hddLog(VOS_TRACE_LEVEL_INFO,
1360 "%s: No Probe Response IE received in set beacon",
1361 __func__);
1362 }
1363
1364 // Added for AssocResp IE
1365 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1366 {
1367 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1368 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1369 params->assocresp_ies_len, NULL,
1370 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1371 {
1372 hddLog(LOGE,
1373 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001374 ret = -EINVAL;
1375 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001376 }
1377
1378 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1379 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1380 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1381 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1382 == eHAL_STATUS_FAILURE)
1383 {
1384 hddLog(LOGE,
1385 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001386 ret = -EINVAL;
1387 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 }
1389 }
1390 else
1391 {
1392 hddLog(VOS_TRACE_LEVEL_INFO,
1393 "%s: No Assoc Response IE received in set beacon",
1394 __func__);
1395
1396 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1397 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1398 eANI_BOOLEAN_FALSE) )
1399 {
1400 hddLog(LOGE,
1401 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1402 }
1403 }
1404
Jeff Johnsone7245742012-09-05 17:12:55 -07001405done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301407 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001408}
Jeff Johnson295189b2012-06-20 16:38:30 -07001409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301410/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 * FUNCTION: wlan_hdd_validate_operation_channel
1412 * called by wlan_hdd_cfg80211_start_bss() and
1413 * wlan_hdd_cfg80211_set_channel()
1414 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301415 * channel list.
1416 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001417VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001418{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301419
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 v_U32_t num_ch = 0;
1421 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1422 u32 indx = 0;
1423 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301424 v_U8_t fValidChannel = FALSE, count = 0;
1425 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301426
Jeff Johnson295189b2012-06-20 16:38:30 -07001427 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1428
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301429 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001430 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301431 /* Validate the channel */
1432 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001433 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301434 if ( channel == rfChannels[count].channelNum )
1435 {
1436 fValidChannel = TRUE;
1437 break;
1438 }
1439 }
1440 if (fValidChannel != TRUE)
1441 {
1442 hddLog(VOS_TRACE_LEVEL_ERROR,
1443 "%s: Invalid Channel [%d]", __func__, channel);
1444 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 }
1446 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301447 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301449 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1450 valid_ch, &num_ch))
1451 {
1452 hddLog(VOS_TRACE_LEVEL_ERROR,
1453 "%s: failed to get valid channel list", __func__);
1454 return VOS_STATUS_E_FAILURE;
1455 }
1456 for (indx = 0; indx < num_ch; indx++)
1457 {
1458 if (channel == valid_ch[indx])
1459 {
1460 break;
1461 }
1462 }
1463
1464 if (indx >= num_ch)
1465 {
1466 hddLog(VOS_TRACE_LEVEL_ERROR,
1467 "%s: Invalid Channel [%d]", __func__, channel);
1468 return VOS_STATUS_E_FAILURE;
1469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001470 }
1471 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301472
Jeff Johnson295189b2012-06-20 16:38:30 -07001473}
1474
Viral Modi3a32cc52013-02-08 11:14:52 -08001475/**
1476 * FUNCTION: wlan_hdd_cfg80211_set_channel
1477 * This function is used to set the channel number
1478 */
1479static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1480 struct ieee80211_channel *chan,
1481 enum nl80211_channel_type channel_type
1482 )
1483{
1484 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001485 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001486 hdd_adapter_t *pAdapter = NULL;
1487 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301488 hdd_context_t *pHddCtx;
1489 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001490
1491 ENTER();
1492
1493 if( NULL == dev )
1494 {
1495 hddLog(VOS_TRACE_LEVEL_ERROR,
1496 "%s: Called with dev = NULL.\n", __func__);
1497 return -ENODEV;
1498 }
1499 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1500
1501 hddLog(VOS_TRACE_LEVEL_INFO,
1502 "%s: device_mode = %d freq = %d \n",__func__,
1503 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301504
1505 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1506 status = wlan_hdd_validate_context(pHddCtx);
1507
1508 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1511 "%s: HDD context is not valid", __func__);
1512 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001513 }
1514
1515 /*
1516 * Do freq to chan conversion
1517 * TODO: for 11a
1518 */
1519
1520 channel = ieee80211_frequency_to_channel(freq);
1521
1522 /* Check freq range */
1523 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1524 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1525 {
1526 hddLog(VOS_TRACE_LEVEL_ERROR,
1527 "%s: Channel [%d] is outside valid range from %d to %d\n",
1528 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1529 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1530 return -EINVAL;
1531 }
1532
1533 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1534
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301535 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1536 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001537 {
1538 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1539 {
1540 hddLog(VOS_TRACE_LEVEL_ERROR,
1541 "%s: Invalid Channel [%d] \n", __func__, channel);
1542 return -EINVAL;
1543 }
1544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1545 "%s: set channel to [%d] for device mode =%d",
1546 __func__, channel,pAdapter->device_mode);
1547 }
1548 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001549 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001550 )
1551 {
1552 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1553 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1554 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1555
1556 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1557 {
1558 /* Link is up then return cant set channel*/
1559 hddLog( VOS_TRACE_LEVEL_ERROR,
1560 "%s: IBSS Associated, can't set the channel\n", __func__);
1561 return -EINVAL;
1562 }
1563
1564 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1565 pHddStaCtx->conn_info.operationChannel = channel;
1566 pRoamProfile->ChannelInfo.ChannelList =
1567 &pHddStaCtx->conn_info.operationChannel;
1568 }
1569 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001570 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001571 )
1572 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301573 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1574 {
1575 if(VOS_STATUS_SUCCESS !=
1576 wlan_hdd_validate_operation_channel(pAdapter,channel))
1577 {
1578 hddLog(VOS_TRACE_LEVEL_ERROR,
1579 "%s: Invalid Channel [%d] \n", __func__, channel);
1580 return -EINVAL;
1581 }
1582 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1583 }
1584 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001585 {
1586 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1587
1588 /* If auto channel selection is configured as enable/ 1 then ignore
1589 channel set by supplicant
1590 */
1591 if ( cfg_param->apAutoChannelSelection )
1592 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301593 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1594 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001595 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1596 "%s: set channel to auto channel (0) for device mode =%d",
1597 __func__, pAdapter->device_mode);
1598 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301599 else
1600 {
1601 if(VOS_STATUS_SUCCESS !=
1602 wlan_hdd_validate_operation_channel(pAdapter,channel))
1603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR,
1605 "%s: Invalid Channel [%d] \n", __func__, channel);
1606 return -EINVAL;
1607 }
1608 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1609 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001610 }
1611 }
1612 else
1613 {
1614 hddLog(VOS_TRACE_LEVEL_FATAL,
1615 "%s: Invalid device mode failed to set valid channel", __func__);
1616 return -EINVAL;
1617 }
1618 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301619 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001620}
1621
Jeff Johnson295189b2012-06-20 16:38:30 -07001622#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1623static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1624 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001625#else
1626static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1627 struct cfg80211_beacon_data *params,
1628 const u8 *ssid, size_t ssid_len,
1629 enum nl80211_hidden_ssid hidden_ssid)
1630#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001631{
1632 tsap_Config_t *pConfig;
1633 beacon_data_t *pBeacon = NULL;
1634 struct ieee80211_mgmt *pMgmt_frame;
1635 v_U8_t *pIe=NULL;
1636 v_U16_t capab_info;
1637 eCsrAuthType RSNAuthType;
1638 eCsrEncryptionType RSNEncryptType;
1639 eCsrEncryptionType mcRSNEncryptType;
1640 int status = VOS_STATUS_SUCCESS;
1641 tpWLAN_SAPEventCB pSapEventCallback;
1642 hdd_hostapd_state_t *pHostapdState;
1643 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1644 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301645 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 struct qc_mac_acl_entry *acl_entry = NULL;
1647 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001648 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001649
1650 ENTER();
1651
1652 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1653
1654 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1655
1656 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1657
1658 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1659
1660 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1661
1662 //channel is already set in the set_channel Call back
1663 //pConfig->channel = pCommitConfig->channel;
1664
1665 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301666 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1668
1669 pConfig->dtim_period = pBeacon->dtim_period;
1670
1671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1672 pConfig->dtim_period);
1673
1674
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001675 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001676 {
1677 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001679 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001681 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001682 pConfig->ieee80211d = 1;
1683 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1684 sme_setRegInfo(hHal, pConfig->countryCode);
1685 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001686 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001687 else
1688 {
1689 pConfig->ieee80211d = 0;
1690 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301691 /*
1692 * If auto channel is configured i.e. channel is 0,
1693 * so skip channel validation.
1694 */
1695 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1696 {
1697 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1701 return -EINVAL;
1702 }
1703 }
1704 else
1705 {
1706 if(1 != pHddCtx->is_dynamic_channel_range_set)
1707 {
1708 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1709 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1710 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1711 }
1712 pHddCtx->is_dynamic_channel_range_set = 0;
1713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001715 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 {
1717 pConfig->ieee80211d = 0;
1718 }
1719 pConfig->authType = eSAP_AUTO_SWITCH;
1720
1721 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301722
1723 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1725
1726 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1727
1728 /*Set wps station to configured*/
1729 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1730
1731 if(pIe)
1732 {
1733 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1734 {
1735 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1736 return -EINVAL;
1737 }
1738 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1739 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001740 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001741 /* Check 15 bit of WPS IE as it contain information for wps state
1742 * WPS state
1743 */
1744 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1745 {
1746 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1747 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1748 {
1749 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1750 }
1751 }
1752 }
1753 else
1754 {
1755 pConfig->wps_state = SAP_WPS_DISABLED;
1756 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301757 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001758
1759 pConfig->RSNWPAReqIELength = 0;
1760 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301761 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 WLAN_EID_RSN);
1763 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301764 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001765 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1766 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1767 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301768 /* The actual processing may eventually be more extensive than
1769 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001770 * by the app.
1771 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301772 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001773 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1774 &RSNEncryptType,
1775 &mcRSNEncryptType,
1776 &RSNAuthType,
1777 pConfig->pRSNWPAReqIE[1]+2,
1778 pConfig->pRSNWPAReqIE );
1779
1780 if( VOS_STATUS_SUCCESS == status )
1781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301782 /* Now copy over all the security attributes you have
1783 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001784 * */
1785 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1786 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1787 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1788 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301789 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001790 "EncryptionType = %d mcEncryptionType = %d\n"),
1791 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1792 }
1793 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301794
Jeff Johnson295189b2012-06-20 16:38:30 -07001795 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1796 pBeacon->tail, pBeacon->tail_len);
1797
1798 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1799 {
1800 if (pConfig->pRSNWPAReqIE)
1801 {
1802 /*Mixed mode WPA/WPA2*/
1803 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1804 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1805 }
1806 else
1807 {
1808 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1809 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1810 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301811 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001812 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1813 &RSNEncryptType,
1814 &mcRSNEncryptType,
1815 &RSNAuthType,
1816 pConfig->pRSNWPAReqIE[1]+2,
1817 pConfig->pRSNWPAReqIE );
1818
1819 if( VOS_STATUS_SUCCESS == status )
1820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301821 /* Now copy over all the security attributes you have
1822 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001823 * */
1824 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1825 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1826 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1827 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301828 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001829 "EncryptionType = %d mcEncryptionType = %d\n"),
1830 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1831 }
1832 }
1833 }
1834
Jeff Johnson4416a782013-03-25 14:17:50 -07001835 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1836 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1837 return -EINVAL;
1838 }
1839
Jeff Johnson295189b2012-06-20 16:38:30 -07001840 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1841
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001842#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001843 if (params->ssid != NULL)
1844 {
1845 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1846 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1847 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1848 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1849 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001850#else
1851 if (ssid != NULL)
1852 {
1853 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1854 pConfig->SSIDinfo.ssid.length = ssid_len;
1855 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1856 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1857 }
1858#endif
1859
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301860 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301862
Jeff Johnson295189b2012-06-20 16:38:30 -07001863 /* default value */
1864 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1865 pConfig->num_accept_mac = 0;
1866 pConfig->num_deny_mac = 0;
1867
1868 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1869 pBeacon->tail, pBeacon->tail_len);
1870
1871 /* pIe for black list is following form:
1872 type : 1 byte
1873 length : 1 byte
1874 OUI : 4 bytes
1875 acl type : 1 byte
1876 no of mac addr in black list: 1 byte
1877 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301878 */
1879 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001880 {
1881 pConfig->SapMacaddr_acl = pIe[6];
1882 pConfig->num_deny_mac = pIe[7];
1883 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1884 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301885 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1886 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001887 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1888 for (i = 0; i < pConfig->num_deny_mac; i++)
1889 {
1890 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1891 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001893 }
1894 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1895 pBeacon->tail, pBeacon->tail_len);
1896
1897 /* pIe for white list is following form:
1898 type : 1 byte
1899 length : 1 byte
1900 OUI : 4 bytes
1901 acl type : 1 byte
1902 no of mac addr in white list: 1 byte
1903 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301904 */
1905 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 {
1907 pConfig->SapMacaddr_acl = pIe[6];
1908 pConfig->num_accept_mac = pIe[7];
1909 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1910 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301911 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1912 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1914 for (i = 0; i < pConfig->num_accept_mac; i++)
1915 {
1916 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1917 acl_entry++;
1918 }
1919 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301920
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1922
Jeff Johnsone7245742012-09-05 17:12:55 -07001923#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001924 /* Overwrite the hostapd setting for HW mode only for 11ac.
1925 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1926 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1927 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1928 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301929 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001930 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1931 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001932 {
1933 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1934 }
1935#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301936
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001937 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1938 {
1939 sme_SelectCBMode(hHal,
1940 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1941 pConfig->channel);
1942 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 // ht_capab is not what the name conveys,this is used for protection bitmap
1944 pConfig->ht_capab =
1945 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1946
1947 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1948 {
1949 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1950 return -EINVAL;
1951 }
1952
1953 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301954 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1956 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301957 pConfig->obssProtEnabled =
1958 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301960 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301962 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1964 (int)pConfig->channel);
1965 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301966 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1967 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301969 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1971 pConfig->protEnabled, pConfig->obssProtEnabled);
1972
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301973 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 {
1975 //Bss already started. just return.
1976 //TODO Probably it should update some beacon params.
1977 hddLog( LOGE, "Bss Already started...Ignore the request");
1978 EXIT();
1979 return 0;
1980 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301981
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 pConfig->persona = pHostapdAdapter->device_mode;
1983
1984 pSapEventCallback = hdd_hostapd_SAPEventCB;
1985 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1986 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1987 {
1988 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1989 return -EINVAL;
1990 }
1991
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301992 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001993 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1994
1995 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301996
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301998 {
1999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 ("ERROR: HDD vos wait for single_event failed!!\n"));
2001 VOS_ASSERT(0);
2002 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302003
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 //Succesfully started Bss update the state bit.
2005 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2006
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002007#ifdef WLAN_FEATURE_P2P_DEBUG
2008 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2009 {
2010 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2011 {
2012 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2013 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002014 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002015 }
2016 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2017 {
2018 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2019 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002020 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002021 }
2022 }
2023#endif
2024
Jeff Johnson295189b2012-06-20 16:38:30 -07002025 pHostapdState->bCommit = TRUE;
2026 EXIT();
2027
2028 return 0;
2029}
2030
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002031#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302032static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2033 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 struct beacon_parameters *params)
2035{
2036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302037 hdd_context_t *pHddCtx;
2038 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002039
2040 ENTER();
2041
2042 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2043
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302044 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2045 status = wlan_hdd_validate_context(pHddCtx);
2046
2047 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2050 "%s: HDD context is not valid", __func__);
2051 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002052 }
2053
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302054 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 )
2057 {
2058 beacon_data_t *old,*new;
2059
2060 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302061
Jeff Johnson295189b2012-06-20 16:38:30 -07002062 if (old)
2063 return -EALREADY;
2064
2065 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2066
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302067 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002068 {
2069 hddLog(VOS_TRACE_LEVEL_FATAL,
2070 "%s:Error!!! Allocating the new beacon\n",__func__);
2071 return -EINVAL;
2072 }
2073
2074 pAdapter->sessionCtx.ap.beacon = new;
2075
2076 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2077 }
2078
2079 EXIT();
2080 return status;
2081}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302082
2083static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002084 struct net_device *dev,
2085 struct beacon_parameters *params)
2086{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302088 hdd_context_t *pHddCtx;
2089 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002090
2091 ENTER();
2092
2093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2094 __func__,pAdapter->device_mode);
2095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2097 status = wlan_hdd_validate_context(pHddCtx);
2098
2099 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2102 "%s: HDD context is not valid", __func__);
2103 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002104 }
2105
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302106 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302108 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 {
2110 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302111
Jeff Johnson295189b2012-06-20 16:38:30 -07002112 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302113
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 if (!old)
2115 return -ENOENT;
2116
2117 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2118
2119 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302120 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 "%s: Error!!! Allocating the new beacon\n",__func__);
2122 return -EINVAL;
2123 }
2124
2125 pAdapter->sessionCtx.ap.beacon = new;
2126
2127 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2128 }
2129
2130 EXIT();
2131 return status;
2132}
2133
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002134#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2135
2136#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002137static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2138 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002139#else
2140static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2141 struct net_device *dev)
2142#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002143{
2144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002145 hdd_context_t *pHddCtx = NULL;
2146 hdd_scaninfo_t *pScanInfo = NULL;
2147 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302148 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002149
2150 ENTER();
2151
2152 if (NULL == pAdapter)
2153 {
2154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002155 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 return -ENODEV;
2157 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002158
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302159 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2160 status = wlan_hdd_validate_context(pHddCtx);
2161
2162 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002163 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2165 "%s: HDD context is not valid", __func__);
2166 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002167 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002168
2169 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2170 if (NULL == staAdapter)
2171 {
2172 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2173 if (NULL == staAdapter)
2174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002176 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002177 return -ENODEV;
2178 }
2179 }
2180
2181 pScanInfo = &pHddCtx->scan_info;
2182
Jeff Johnson295189b2012-06-20 16:38:30 -07002183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2184 __func__,pAdapter->device_mode);
2185
Jeff Johnsone7245742012-09-05 17:12:55 -07002186 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2187 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002188 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002189 hdd_abort_mac_scan(staAdapter->pHddCtx);
2190 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002191 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002192 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2193 if (!status)
2194 {
2195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002196 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002197 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002198 VOS_ASSERT(pScanInfo->mScanPending);
2199 return 0;
2200 }
2201 }
2202
Jeff Johnson295189b2012-06-20 16:38:30 -07002203 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 )
2206 {
2207 beacon_data_t *old;
2208
2209 old = pAdapter->sessionCtx.ap.beacon;
2210
2211 if (!old)
2212 return -ENOENT;
2213
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002215
2216 mutex_lock(&pHddCtx->sap_lock);
2217 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2218 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002219 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 {
2221 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2222
2223 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2224
2225 if (!VOS_IS_STATUS_SUCCESS(status))
2226 {
2227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2228 ("ERROR: HDD vos wait for single_event failed!!\n"));
2229 VOS_ASSERT(0);
2230 }
2231 }
2232 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2233 }
2234 mutex_unlock(&pHddCtx->sap_lock);
2235
2236 if(status != VOS_STATUS_SUCCESS)
2237 {
2238 hddLog(VOS_TRACE_LEVEL_FATAL,
2239 "%s:Error!!! Stopping the BSS\n",__func__);
2240 return -EINVAL;
2241 }
2242
Jeff Johnson4416a782013-03-25 14:17:50 -07002243 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2245 ==eHAL_STATUS_FAILURE)
2246 {
2247 hddLog(LOGE,
2248 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2249 }
2250
Jeff Johnson4416a782013-03-25 14:17:50 -07002251 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2253 eANI_BOOLEAN_FALSE) )
2254 {
2255 hddLog(LOGE,
2256 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2257 }
2258
2259 // Reset WNI_CFG_PROBE_RSP Flags
2260 wlan_hdd_reset_prob_rspies(pAdapter);
2261
2262 pAdapter->sessionCtx.ap.beacon = NULL;
2263 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002264#ifdef WLAN_FEATURE_P2P_DEBUG
2265 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2266 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2267 {
2268 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2269 "GO got removed");
2270 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2271 }
2272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002273 }
2274 EXIT();
2275 return status;
2276}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002277
2278#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2279
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302280static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2281 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002282 struct cfg80211_ap_settings *params)
2283{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302284 hdd_adapter_t *pAdapter;
2285 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302286 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002287
2288 ENTER();
2289
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302290 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002291 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302293 "%s: Device is Null", __func__);
2294 return -ENODEV;
2295 }
2296
2297 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2298 if (NULL == pAdapter)
2299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 "%s: HDD adapter is Null", __func__);
2302 return -ENODEV;
2303 }
2304
2305 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2306 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302308 "%s: HDD adapter magic is invalid", __func__);
2309 return -ENODEV;
2310 }
2311
2312 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302313 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302314
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302315 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302316 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2318 "%s: HDD context is not valid", __func__);
2319 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302320 }
2321
2322 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2323 __func__, pAdapter->device_mode);
2324
2325 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002326 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327 )
2328 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302329 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002330
2331 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302332
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002333 if (old)
2334 return -EALREADY;
2335
2336 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2337
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302338 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002339 {
2340 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302341 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002342 return -EINVAL;
2343 }
2344 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2346 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2347#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002348 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2349 params->ssid_len, params->hidden_ssid);
2350 }
2351
2352 EXIT();
2353 return status;
2354}
2355
2356
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302357static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002358 struct net_device *dev,
2359 struct cfg80211_beacon_data *params)
2360{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302361 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302362 hdd_context_t *pHddCtx;
2363 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364
2365 ENTER();
2366
2367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2368 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302369
2370 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2371 status = wlan_hdd_validate_context(pHddCtx);
2372
2373 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002374 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2376 "%s: HDD context is not valid", __func__);
2377 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002378 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002381 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302382 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002383 {
2384 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302385
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002386 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302387
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002388 if (!old)
2389 return -ENOENT;
2390
2391 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2392
2393 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302394 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002395 "%s: Error!!! Allocating the new beacon\n",__func__);
2396 return -EINVAL;
2397 }
2398
2399 pAdapter->sessionCtx.ap.beacon = new;
2400
2401 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2402 }
2403
2404 EXIT();
2405 return status;
2406}
2407
2408#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2409
Jeff Johnson295189b2012-06-20 16:38:30 -07002410
2411static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2412 struct net_device *dev,
2413 struct bss_parameters *params)
2414{
2415 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2416
2417 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302418
Jeff Johnson295189b2012-06-20 16:38:30 -07002419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2420 __func__,pAdapter->device_mode);
2421
2422 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302424 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 {
2426 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2427 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302428 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 {
2430 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 }
2433
2434 EXIT();
2435 return 0;
2436}
2437
2438/*
2439 * FUNCTION: wlan_hdd_cfg80211_change_iface
2440 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2441 */
2442int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2443 struct net_device *ndev,
2444 enum nl80211_iftype type,
2445 u32 *flags,
2446 struct vif_params *params
2447 )
2448{
2449 struct wireless_dev *wdev;
2450 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2451 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002452 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 tCsrRoamProfile *pRoamProfile = NULL;
2454 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302455 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 eMib_dot11DesiredBssType connectedBssType;
2457 VOS_STATUS status;
2458
2459 ENTER();
2460
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302461 status = wlan_hdd_validate_context(pHddCtx);
2462
2463 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002464 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: HDD context is not valid", __func__);
2467 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 }
2469
2470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2471 __func__, pAdapter->device_mode);
2472
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302473 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002474 wdev = ndev->ieee80211_ptr;
2475
2476#ifdef WLAN_BTAMP_FEATURE
2477 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2478 (NL80211_IFTYPE_ADHOC == type)||
2479 (NL80211_IFTYPE_AP == type)||
2480 (NL80211_IFTYPE_P2P_GO == type))
2481 {
2482 pHddCtx->isAmpAllowed = VOS_FALSE;
2483 // stop AMP traffic
2484 status = WLANBAP_StopAmp();
2485 if(VOS_STATUS_SUCCESS != status )
2486 {
2487 pHddCtx->isAmpAllowed = VOS_TRUE;
2488 hddLog(VOS_TRACE_LEVEL_FATAL,
2489 "%s: Failed to stop AMP", __func__);
2490 return -EINVAL;
2491 }
2492 }
2493#endif //WLAN_BTAMP_FEATURE
2494 /* Reset the current device mode bit mask*/
2495 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2496
2497 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002498 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002499 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 )
2501 {
2502 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2503 pRoamProfile = &pWextState->roamProfile;
2504 LastBSSType = pRoamProfile->BSSType;
2505
2506 switch (type)
2507 {
2508 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002510 hddLog(VOS_TRACE_LEVEL_INFO,
2511 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2512 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002513#ifdef WLAN_FEATURE_11AC
2514 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2515 {
2516 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2517 }
2518#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302519 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002520 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002521 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002522 //Check for sub-string p2p to confirm its a p2p interface
2523 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302524 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002525 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2526 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2527 }
2528 else
2529 {
2530 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002531 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002533 break;
2534 case NL80211_IFTYPE_ADHOC:
2535 hddLog(VOS_TRACE_LEVEL_INFO,
2536 "%s: setting interface Type to ADHOC", __func__);
2537 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2538 pRoamProfile->phyMode =
2539 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002540 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 wdev->iftype = type;
2542 break;
2543
2544 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 {
2547 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2548 "%s: setting interface Type to %s", __func__,
2549 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2550
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002551 //Cancel any remain on channel for GO mode
2552 if (NL80211_IFTYPE_P2P_GO == type)
2553 {
2554 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2555 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002556 if (NL80211_IFTYPE_AP == type)
2557 {
2558 /* As Loading WLAN Driver one interface being created for p2p device
2559 * address. This will take one HW STA and the max number of clients
2560 * that can connect to softAP will be reduced by one. so while changing
2561 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2562 * interface as it is not required in SoftAP mode.
2563 */
2564
2565 // Get P2P Adapter
2566 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2567
2568 if (pP2pAdapter)
2569 {
2570 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2571 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2572 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2573 }
2574 }
2575
Jeff Johnson295189b2012-06-20 16:38:30 -07002576 //De-init the adapter.
2577 hdd_stop_adapter( pHddCtx, pAdapter );
2578 hdd_deinit_adapter( pHddCtx, pAdapter );
2579 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002580 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2581 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002582
2583 //Disable BMPS and IMPS if enabled
2584 //before starting Go
2585 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302587 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002588 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2589 {
2590 //Fail to Exit BMPS
2591 VOS_ASSERT(0);
2592 }
2593 }
2594
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002595 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2596 (pConfig->apRandomBssidEnabled))
2597 {
2598 /* To meet Android requirements create a randomized
2599 MAC address of the form 02:1A:11:Fx:xx:xx */
2600 get_random_bytes(&ndev->dev_addr[3], 3);
2601 ndev->dev_addr[0] = 0x02;
2602 ndev->dev_addr[1] = 0x1A;
2603 ndev->dev_addr[2] = 0x11;
2604 ndev->dev_addr[3] |= 0xF0;
2605 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2606 VOS_MAC_ADDR_SIZE);
2607 pr_info("wlan: Generated HotSpot BSSID "
2608 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2609 ndev->dev_addr[0],
2610 ndev->dev_addr[1],
2611 ndev->dev_addr[2],
2612 ndev->dev_addr[3],
2613 ndev->dev_addr[4],
2614 ndev->dev_addr[5]);
2615 }
2616
Jeff Johnson295189b2012-06-20 16:38:30 -07002617 hdd_set_ap_ops( pAdapter->dev );
2618
2619 status = hdd_init_ap_mode(pAdapter);
2620 if(status != VOS_STATUS_SUCCESS)
2621 {
2622 hddLog(VOS_TRACE_LEVEL_FATAL,
2623 "%s: Error initializing the ap mode", __func__);
2624 return -EINVAL;
2625 }
2626 hdd_set_conparam(1);
2627
Jeff Johnson295189b2012-06-20 16:38:30 -07002628 /*interface type changed update in wiphy structure*/
2629 if(wdev)
2630 {
2631 wdev->iftype = type;
2632 pHddCtx->change_iface = type;
2633 }
2634 else
2635 {
2636 hddLog(VOS_TRACE_LEVEL_ERROR,
2637 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2638 return -EINVAL;
2639 }
2640 goto done;
2641 }
2642
2643 default:
2644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2645 __func__);
2646 return -EOPNOTSUPP;
2647 }
2648 }
2649 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002650 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002651 )
2652 {
2653 switch(type)
2654 {
2655 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002656 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002658 hdd_stop_adapter( pHddCtx, pAdapter );
2659 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002660 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002661 //Check for sub-string p2p to confirm its a p2p interface
2662 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002663 {
2664 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2665 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2666 }
2667 else
2668 {
2669 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002671 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002672 hdd_set_conparam(0);
2673 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2675 hdd_set_station_ops( pAdapter->dev );
2676 status = hdd_init_station_mode( pAdapter );
2677 if( VOS_STATUS_SUCCESS != status )
2678 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002679 /* In case of JB, for P2P-GO, only change interface will be called,
2680 * This is the right place to enable back bmps_imps()
2681 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302682 if (pHddCtx->hdd_wlan_suspended)
2683 {
2684 hdd_set_pwrparams(pHddCtx);
2685 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002686 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 goto done;
2688 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002689 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002691 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2692 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 goto done;
2694 default:
2695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2696 __func__);
2697 return -EOPNOTSUPP;
2698
2699 }
2700
2701 }
2702 else
2703 {
2704 return -EOPNOTSUPP;
2705 }
2706
2707
2708 if(pRoamProfile)
2709 {
2710 if ( LastBSSType != pRoamProfile->BSSType )
2711 {
2712 /*interface type changed update in wiphy structure*/
2713 wdev->iftype = type;
2714
2715 /*the BSS mode changed, We need to issue disconnect
2716 if connected or in IBSS disconnect state*/
2717 if ( hdd_connGetConnectedBssType(
2718 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2719 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2720 {
2721 /*need to issue a disconnect to CSR.*/
2722 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2723 if( eHAL_STATUS_SUCCESS ==
2724 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2725 pAdapter->sessionId,
2726 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2727 {
2728 wait_for_completion_interruptible_timeout(
2729 &pAdapter->disconnect_comp_var,
2730 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2731 }
2732 }
2733 }
2734 }
2735
2736done:
2737 /*set bitmask based on updated value*/
2738 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2739#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302740 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002741 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2742 {
2743 //we are ok to do AMP
2744 pHddCtx->isAmpAllowed = VOS_TRUE;
2745 }
2746#endif //WLAN_BTAMP_FEATURE
2747 EXIT();
2748 return 0;
2749}
2750
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002751#ifdef FEATURE_WLAN_TDLS
2752static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2753 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2754{
2755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2756 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2757 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002758 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002759
2760 ENTER();
2761
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302762 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002763 {
2764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2765 "Invalid arguments");
2766 return -EINVAL;
2767 }
Hoonki Lee27511902013-03-14 18:19:06 -07002768
2769 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2770 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2771 {
2772 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2773 "%s: TDLS mode is disabled OR not enabled in FW."
2774 MAC_ADDRESS_STR " Request declined.",
2775 __func__, MAC_ADDR_ARRAY(mac));
2776 return -ENOTSUPP;
2777 }
2778
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002779 if (pHddCtx->isLogpInProgress)
2780 {
2781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2782 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002783 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002784 return -EBUSY;
2785 }
2786
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002787 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2788
2789 if ( NULL == pTdlsPeer ) {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2791 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2792 __func__, MAC_ADDR_ARRAY(mac), update);
2793 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002794 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002795
2796 /* in add station, we accept existing valid staId if there is */
2797 if ((0 == update) &&
2798 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2799 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002800 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002801 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002802 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002803 " link_status %d. staId %d. add station ignored.",
2804 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2805 return 0;
2806 }
2807 /* in change station, we accept only when staId is valid */
2808 if ((1 == update) &&
2809 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2810 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2811 {
2812 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2813 "%s: " MAC_ADDRESS_STR
2814 " link status %d. staId %d. change station %s.",
2815 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2816 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2817 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002818 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002819
2820 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002821 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002822 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: " MAC_ADDRESS_STR
2825 " TDLS setup is ongoing. Request declined.",
2826 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002827 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002828 }
2829
2830 /* first to check if we reached to maximum supported TDLS peer.
2831 TODO: for now, return -EPERM looks working fine,
2832 but need to check if any other errno fit into this category.*/
2833 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2834 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2836 "%s: " MAC_ADDRESS_STR
2837 " TDLS Max peer already connected. Request declined.",
2838 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002839 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002840 }
2841 else
2842 {
2843 hddTdlsPeer_t *pTdlsPeer;
2844 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002845 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002846 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2848 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2849 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002850 return -EPERM;
2851 }
2852 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002853 if (0 == update)
2854 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002855
Jeff Johnsond75fe012013-04-06 10:53:06 -07002856 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302857 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002858 {
2859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2860 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002861 if(StaParams->htcap_present)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "ht_capa->extended_capabilities: %0x",
2867 StaParams->HTCap.extendedHtCapInfo);
2868 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002869 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2870 "params->capability: %0x",StaParams->capability);
2871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2872 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002873 if(StaParams->vhtcap_present)
2874 {
2875 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2876 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2877 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2878 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2879 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002880 {
2881 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002883 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2884 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2885 "[%d]: %x ", i, StaParams->supported_rates[i]);
2886 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002887 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302888 else if ((1 == update) && (NULL == StaParams))
2889 {
2890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2891 "%s : update is true, but staParams is NULL. Error!", __func__);
2892 return -EPERM;
2893 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002894
2895 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2896
2897 if (!update)
2898 {
2899 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2900 pAdapter->sessionId, mac);
2901 }
2902 else
2903 {
2904 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2905 pAdapter->sessionId, mac, StaParams);
2906 }
2907
2908 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2909 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2910
2911 if (!status)
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: timeout waiting for tdls add station indication",
2915 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002916 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002917 }
2918 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2919 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002921 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002922 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002923 }
2924
2925 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002926
2927error:
2928 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2929 return -EPERM;
2930
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002931}
2932#endif
2933
Jeff Johnson295189b2012-06-20 16:38:30 -07002934static int wlan_hdd_change_station(struct wiphy *wiphy,
2935 struct net_device *dev,
2936 u8 *mac,
2937 struct station_parameters *params)
2938{
2939 VOS_STATUS status = VOS_STATUS_SUCCESS;
2940 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302941 hdd_context_t *pHddCtx;
2942 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002943 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002944#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002945 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002946 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002947#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002948 ENTER();
2949
Gopichand Nakkala29149562013-05-10 21:43:41 +05302950 if ((NULL == pAdapter))
2951 {
2952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2953 "invalid adapter ");
2954 return -EINVAL;
2955 }
2956
2957 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2958 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2959
2960 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2961 {
2962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2963 "invalid HDD state or HDD station context");
2964 return -EINVAL;
2965 }
2966
2967 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002968 {
2969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2970 "%s:LOGP in Progress. Ignore!!!", __func__);
2971 return -EAGAIN;
2972 }
2973
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2975
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002976 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2977 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002978 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002979 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302981 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 WLANTL_STA_AUTHENTICATED);
2983
Gopichand Nakkala29149562013-05-10 21:43:41 +05302984 if (status != VOS_STATUS_SUCCESS)
2985 {
2986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2987 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2988 return -EINVAL;
2989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002990 }
2991 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002992 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2993 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302994#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002995 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2996 StaParams.capability = params->capability;
2997 StaParams.uapsd_queues = params->uapsd_queues;
2998 StaParams.max_sp = params->max_sp;
2999
3000 if (0 != params->ext_capab_len)
3001 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3002 sizeof(StaParams.extn_capability));
3003
3004 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003005 {
3006 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003007 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003008 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003009
3010 StaParams.supported_rates_len = params->supported_rates_len;
3011
3012 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3013 * The supported_rates array , for all the structures propogating till Add Sta
3014 * to the firmware has to be modified , if the supplicant (ieee80211) is
3015 * modified to send more rates.
3016 */
3017
3018 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3019 */
3020 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3021 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3022
3023 if (0 != StaParams.supported_rates_len) {
3024 int i = 0;
3025 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3026 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003028 "Supported Rates with Length %d", StaParams.supported_rates_len);
3029 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003031 "[%d]: %0x", i, StaParams.supported_rates[i]);
3032 }
3033
3034 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003035 {
3036 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003037 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003038 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003039
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003040 if (0 != params->ext_capab_len ) {
3041 /*Define A Macro : TODO Sunil*/
3042 if ((1<<4) & StaParams.extn_capability[3]) {
3043 isBufSta = 1;
3044 }
3045 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003046 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3047 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003048 //if (VOS_STATUS_SUCCESS != status) {
3049 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3050 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3051 // return -EINVAL;
3052 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003053 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3054
3055 if (VOS_STATUS_SUCCESS != status) {
3056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3057 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3058 return -EINVAL;
3059 }
3060 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003061#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303062 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3063 {
3064 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3065 WLANTL_STA_AUTHENTICATED);
3066 if (status != VOS_STATUS_SUCCESS)
3067 {
3068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3069 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3070 return -EINVAL;
3071 }
3072 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3074 "%s: TL Moving to Authenticated state", __func__);
3075 }
3076 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303077
Jeff Johnsone7245742012-09-05 17:12:55 -07003078 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 return status;
3080}
3081
3082/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003083 * FUNCTION: wlan_hdd_cfg80211_add_key
3084 * This function is used to initialize the key information
3085 */
3086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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, bool pairwise,
3090 const u8 *mac_addr,
3091 struct key_params *params
3092 )
3093#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003094static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 struct net_device *ndev,
3096 u8 key_index, const u8 *mac_addr,
3097 struct key_params *params
3098 )
3099#endif
3100{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 tCsrRoamSetKey setKey;
3103 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303104 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003105 v_U32_t roamId= 0xFF;
3106 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003107 hdd_hostapd_state_t *pHostapdState;
3108 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003109 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303110 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003111
3112 ENTER();
3113
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3115 status = wlan_hdd_validate_context(pHddCtx);
3116
3117 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003118 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3120 "%s: HDD context is not valid", __func__);
3121 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003122 }
3123
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3125 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003126
3127 if (CSR_MAX_NUM_KEY <= key_index)
3128 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003130 key_index);
3131
3132 return -EINVAL;
3133 }
3134
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003135 if (CSR_MAX_KEY_LEN < params->key_len)
3136 {
3137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3138 params->key_len);
3139
3140 return -EINVAL;
3141 }
3142
3143 hddLog(VOS_TRACE_LEVEL_INFO,
3144 "%s: called with key index = %d & key length %d",
3145 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003146
3147 /*extract key idx, key len and key*/
3148 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3149 setKey.keyId = key_index;
3150 setKey.keyLength = params->key_len;
3151 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3152
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003153 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003154 {
3155 case WLAN_CIPHER_SUITE_WEP40:
3156 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3157 break;
3158
3159 case WLAN_CIPHER_SUITE_WEP104:
3160 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3161 break;
3162
3163 case WLAN_CIPHER_SUITE_TKIP:
3164 {
3165 u8 *pKey = &setKey.Key[0];
3166 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3167
3168 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3169
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003170 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003171
3172 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003173 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003174 |--------------|----------|----------|
3175 <---16bytes---><--8bytes--><--8bytes-->
3176
3177 */
3178 /*Sme expects the 32 bytes key to be in the below order
3179
3180 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003181 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003182 |--------------|----------|----------|
3183 <---16bytes---><--8bytes--><--8bytes-->
3184 */
3185 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003186 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003187
3188 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003189 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003190
3191 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003192 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003193
3194
3195 break;
3196 }
3197
3198 case WLAN_CIPHER_SUITE_CCMP:
3199 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3200 break;
3201
3202#ifdef FEATURE_WLAN_WAPI
3203 case WLAN_CIPHER_SUITE_SMS4:
3204 {
3205 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3206 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3207 params->key, params->key_len);
3208 return 0;
3209 }
3210#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003211
Jeff Johnson295189b2012-06-20 16:38:30 -07003212#ifdef FEATURE_WLAN_CCX
3213 case WLAN_CIPHER_SUITE_KRK:
3214 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3215 break;
3216#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003217
3218#ifdef WLAN_FEATURE_11W
3219 case WLAN_CIPHER_SUITE_AES_CMAC:
3220 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003221 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003222#endif
3223
Jeff Johnson295189b2012-06-20 16:38:30 -07003224 default:
3225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3226 __func__, params->cipher);
3227 return -EOPNOTSUPP;
3228 }
3229
3230 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3231 __func__, setKey.encType);
3232
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003233 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003234#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3235 (!pairwise)
3236#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003237 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003238#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003239 )
3240 {
3241 /* set group key*/
3242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3243 "%s- %d: setting Broadcast key",
3244 __func__, __LINE__);
3245 setKey.keyDirection = eSIR_RX_ONLY;
3246 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3247 }
3248 else
3249 {
3250 /* set pairwise key*/
3251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3252 "%s- %d: setting pairwise key",
3253 __func__, __LINE__);
3254 setKey.keyDirection = eSIR_TX_RX;
3255 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3256 }
3257 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3258 {
3259 setKey.keyDirection = eSIR_TX_RX;
3260 /*Set the group key*/
3261 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3262 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003263
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003264 if ( 0 != status )
3265 {
3266 hddLog(VOS_TRACE_LEVEL_ERROR,
3267 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3268 return -EINVAL;
3269 }
3270 /*Save the keys here and call sme_RoamSetKey for setting
3271 the PTK after peer joins the IBSS network*/
3272 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3273 &setKey, sizeof(tCsrRoamSetKey));
3274 return status;
3275 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303276 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3277 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3278 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003279 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003280 if( pHostapdState->bssState == BSS_START )
3281 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003282 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3283
3284 if ( status != eHAL_STATUS_SUCCESS )
3285 {
3286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3287 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3288 __LINE__, status );
3289 }
3290 }
3291
3292 /* Saving WEP keys */
3293 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3294 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3295 {
3296 //Save the wep key in ap context. Issue setkey after the BSS is started.
3297 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3298 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3299 }
3300 else
3301 {
3302 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003303 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003304 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3305 }
3306 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003307 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3308 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003309 {
3310 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3311 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3312
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303313#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3314 if (!pairwise)
3315#else
3316 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3317#endif
3318 {
3319 /* set group key*/
3320 if (pHddStaCtx->roam_info.deferKeyComplete)
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3323 "%s- %d: Perform Set key Complete",
3324 __func__, __LINE__);
3325 hdd_PerformRoamSetKeyComplete(pAdapter);
3326 }
3327 }
3328
Jeff Johnson295189b2012-06-20 16:38:30 -07003329 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3330
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003331 pWextState->roamProfile.Keys.defaultIndex = key_index;
3332
3333
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003334 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003335 params->key, params->key_len);
3336
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303337
Jeff Johnson295189b2012-06-20 16:38:30 -07003338 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3339
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303340 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003341 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303342 __func__, setKey.peerMac[0], setKey.peerMac[1],
3343 setKey.peerMac[2], setKey.peerMac[3],
3344 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003345 setKey.keyDirection);
3346
3347 vos_status = wlan_hdd_check_ula_done(pAdapter);
3348
3349 if ( vos_status != VOS_STATUS_SUCCESS )
3350 {
3351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3352 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3353 __LINE__, vos_status );
3354
3355 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3356
3357 return -EINVAL;
3358
3359 }
3360
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003361#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303362 /* The supplicant may attempt to set the PTK once pre-authentication
3363 is done. Save the key in the UMAC and include it in the ADD BSS
3364 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003365 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303366 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003367 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303368 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3369 "%s: Update PreAuth Key success", __func__);
3370 return 0;
3371 }
3372 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3373 {
3374 hddLog(VOS_TRACE_LEVEL_ERROR,
3375 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303376 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003377 }
3378#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003379
3380 /* issue set key request to SME*/
3381 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3382 pAdapter->sessionId, &setKey, &roamId );
3383
3384 if ( 0 != status )
3385 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303386 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003387 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3388 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3389 return -EINVAL;
3390 }
3391
3392
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303393 /* in case of IBSS as there was no information available about WEP keys during
3394 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303396 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3397 !( ( IW_AUTH_KEY_MGMT_802_1X
3398 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003399 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3400 )
3401 &&
3402 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3403 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3404 )
3405 )
3406 {
3407 setKey.keyDirection = eSIR_RX_ONLY;
3408 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303410 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303412 __func__, setKey.peerMac[0], setKey.peerMac[1],
3413 setKey.peerMac[2], setKey.peerMac[3],
3414 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003415 setKey.keyDirection);
3416
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303417 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003418 pAdapter->sessionId, &setKey, &roamId );
3419
3420 if ( 0 != status )
3421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303422 hddLog(VOS_TRACE_LEVEL_ERROR,
3423 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003424 __func__, status);
3425 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3426 return -EINVAL;
3427 }
3428 }
3429 }
3430
3431 return 0;
3432}
3433
3434/*
3435 * FUNCTION: wlan_hdd_cfg80211_get_key
3436 * This function is used to get the key information
3437 */
3438#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303439static int wlan_hdd_cfg80211_get_key(
3440 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303442 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003443 const u8 *mac_addr, void *cookie,
3444 void (*callback)(void *cookie, struct key_params*)
3445 )
3446#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303447static int wlan_hdd_cfg80211_get_key(
3448 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 struct net_device *ndev,
3450 u8 key_index, const u8 *mac_addr, void *cookie,
3451 void (*callback)(void *cookie, struct key_params*)
3452 )
3453#endif
3454{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003456 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3457 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3458 struct key_params params;
3459
3460 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303461
Jeff Johnson295189b2012-06-20 16:38:30 -07003462 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3463 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303464
Jeff Johnson295189b2012-06-20 16:38:30 -07003465 memset(&params, 0, sizeof(params));
3466
3467 if (CSR_MAX_NUM_KEY <= key_index)
3468 {
3469 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003471
3472 switch(pRoamProfile->EncryptionType.encryptionType[0])
3473 {
3474 case eCSR_ENCRYPT_TYPE_NONE:
3475 params.cipher = IW_AUTH_CIPHER_NONE;
3476 break;
3477
3478 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3479 case eCSR_ENCRYPT_TYPE_WEP40:
3480 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3481 break;
3482
3483 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3484 case eCSR_ENCRYPT_TYPE_WEP104:
3485 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3486 break;
3487
3488 case eCSR_ENCRYPT_TYPE_TKIP:
3489 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3490 break;
3491
3492 case eCSR_ENCRYPT_TYPE_AES:
3493 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3494 break;
3495
3496 default:
3497 params.cipher = IW_AUTH_CIPHER_NONE;
3498 break;
3499 }
3500
3501 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3502 params.seq_len = 0;
3503 params.seq = NULL;
3504 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3505 callback(cookie, &params);
3506 return 0;
3507}
3508
3509/*
3510 * FUNCTION: wlan_hdd_cfg80211_del_key
3511 * This function is used to delete the key information
3512 */
3513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516 u8 key_index,
3517 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003518 const u8 *mac_addr
3519 )
3520#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303521static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003522 struct net_device *ndev,
3523 u8 key_index,
3524 const u8 *mac_addr
3525 )
3526#endif
3527{
3528 int status = 0;
3529
3530 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303531 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003532 //it is observed that this is invalidating peer
3533 //key index whenever re-key is done. This is affecting data link.
3534 //It should be ok to ignore del_key.
3535#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303536 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3537 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3539 tCsrRoamSetKey setKey;
3540 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303541
Jeff Johnson295189b2012-06-20 16:38:30 -07003542 ENTER();
3543
3544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3545 __func__,pAdapter->device_mode);
3546
3547 if (CSR_MAX_NUM_KEY <= key_index)
3548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003550 key_index);
3551
3552 return -EINVAL;
3553 }
3554
3555 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3556 setKey.keyId = key_index;
3557
3558 if (mac_addr)
3559 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3560 else
3561 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3562
3563 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3564
3565 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303567 )
3568 {
3569
3570 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003571 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3572 if( pHostapdState->bssState == BSS_START)
3573 {
3574 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303575
Jeff Johnson295189b2012-06-20 16:38:30 -07003576 if ( status != eHAL_STATUS_SUCCESS )
3577 {
3578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3580 __LINE__, status );
3581 }
3582 }
3583 }
3584 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303585 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 )
3587 {
3588 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303590 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3591
3592 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003593 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303594 __func__, setKey.peerMac[0], setKey.peerMac[1],
3595 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303597 if(pAdapter->sessionCtx.station.conn_info.connState ==
3598 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303600 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003601 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303602
Jeff Johnson295189b2012-06-20 16:38:30 -07003603 if ( 0 != status )
3604 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303605 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 "%s: sme_RoamSetKey failure, returned %d",
3607 __func__, status);
3608 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3609 return -EINVAL;
3610 }
3611 }
3612 }
3613#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003614 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003615 return status;
3616}
3617
3618/*
3619 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3620 * This function is used to set the default tx key index
3621 */
3622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3623static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3624 struct net_device *ndev,
3625 u8 key_index,
3626 bool unicast, bool multicast)
3627#else
3628static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3629 struct net_device *ndev,
3630 u8 key_index)
3631#endif
3632{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303633 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303634 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303635 hdd_wext_state_t *pWextState;
3636 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303637 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003638
3639 ENTER();
3640
Gopichand Nakkala29149562013-05-10 21:43:41 +05303641 if ((NULL == pAdapter))
3642 {
3643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3644 "invalid adapter");
3645 return -EINVAL;
3646 }
3647
3648 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3649 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3650
3651 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3652 {
3653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3654 "invalid Wext state or HDD context");
3655 return -EINVAL;
3656 }
3657
Jeff Johnson295189b2012-06-20 16:38:30 -07003658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3659 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303660
Jeff Johnson295189b2012-06-20 16:38:30 -07003661 if (CSR_MAX_NUM_KEY <= key_index)
3662 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003664 key_index);
3665
3666 return -EINVAL;
3667 }
3668
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303669 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3670 status = wlan_hdd_validate_context(pHddCtx);
3671
3672 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003673 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3675 "%s: HDD context is not valid", __func__);
3676 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003677 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678
Jeff Johnson295189b2012-06-20 16:38:30 -07003679 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303681 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303683 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003684 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303685 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003686 pWextState->roamProfile.EncryptionType.encryptionType[0])
3687 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688 {
3689 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 tCsrRoamSetKey setKey;
3693 v_U32_t roamId= 0xFF;
3694 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303695
3696 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003697 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303698
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 Keys->defaultIndex = (u8)key_index;
3700 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3701 setKey.keyId = key_index;
3702 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703
3704 vos_mem_copy(&setKey.Key[0],
3705 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303707
Gopichand Nakkala29149562013-05-10 21:43:41 +05303708 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303709
3710 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003711 &pHddStaCtx->conn_info.bssId[0],
3712 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303713
Gopichand Nakkala29149562013-05-10 21:43:41 +05303714 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3715 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3716 eCSR_ENCRYPT_TYPE_WEP104)
3717 {
3718 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3719 even though ap is configured for WEP-40 encryption. In this canse the key length
3720 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3721 type(104) and switching encryption type to 40*/
3722 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3723 eCSR_ENCRYPT_TYPE_WEP40;
3724 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3725 eCSR_ENCRYPT_TYPE_WEP40;
3726 }
3727
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303728 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003729 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303730
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303732 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303734
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 if ( 0 != status )
3736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303737 hddLog(VOS_TRACE_LEVEL_ERROR,
3738 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003739 status);
3740 return -EINVAL;
3741 }
3742 }
3743 }
3744
3745 /* In SoftAp mode setting key direction for default mode */
3746 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3747 {
3748 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3749 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3750 (eCSR_ENCRYPT_TYPE_AES !=
3751 pWextState->roamProfile.EncryptionType.encryptionType[0])
3752 )
3753 {
3754 /* Saving key direction for default key index to TX default */
3755 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3756 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3757 }
3758 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303759
Jeff Johnson295189b2012-06-20 16:38:30 -07003760 return status;
3761}
3762
Jeff Johnson295189b2012-06-20 16:38:30 -07003763/*
3764 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3765 * This function is used to inform the BSS details to nl80211 interface.
3766 */
3767static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3768 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3769{
3770 struct net_device *dev = pAdapter->dev;
3771 struct wireless_dev *wdev = dev->ieee80211_ptr;
3772 struct wiphy *wiphy = wdev->wiphy;
3773 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3774 int chan_no;
3775 int ie_length;
3776 const char *ie;
3777 unsigned int freq;
3778 struct ieee80211_channel *chan;
3779 int rssi = 0;
3780 struct cfg80211_bss *bss = NULL;
3781
3782 ENTER();
3783
3784 if( NULL == pBssDesc )
3785 {
3786 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3787 return bss;
3788 }
3789
3790 chan_no = pBssDesc->channelId;
3791 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3792 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3793
3794 if( NULL == ie )
3795 {
3796 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3797 return bss;
3798 }
3799
3800#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3801 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3802 {
3803 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3804 }
3805 else
3806 {
3807 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3808 }
3809#else
3810 freq = ieee80211_channel_to_frequency(chan_no);
3811#endif
3812
3813 chan = __ieee80211_get_channel(wiphy, freq);
3814
3815 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3816 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3817 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3818 if (bss == NULL)
3819 {
3820 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3821
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303822 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3823 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003824 pBssDesc->capabilityInfo,
3825 pBssDesc->beaconInterval, ie, ie_length,
3826 rssi, GFP_KERNEL ));
3827}
3828 else
3829 {
3830 return bss;
3831 }
3832}
3833
3834
3835
3836/*
3837 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3838 * This function is used to inform the BSS details to nl80211 interface.
3839 */
3840struct cfg80211_bss*
3841wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3842 tSirBssDescription *bss_desc
3843 )
3844{
3845 /*
3846 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3847 already exists in bss data base of cfg80211 for that particular BSS ID.
3848 Using cfg80211_inform_bss_frame to update the bss entry instead of
3849 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3850 now there is no possibility to get the mgmt(probe response) frame from PE,
3851 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3852 cfg80211_inform_bss_frame.
3853 */
3854 struct net_device *dev = pAdapter->dev;
3855 struct wireless_dev *wdev = dev->ieee80211_ptr;
3856 struct wiphy *wiphy = wdev->wiphy;
3857 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003858#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3859 qcom_ie_age *qie_age = NULL;
3860 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3861#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003862 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003864 const char *ie =
3865 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3866 unsigned int freq;
3867 struct ieee80211_channel *chan;
3868 struct ieee80211_mgmt *mgmt =
3869 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3870 struct cfg80211_bss *bss_status = NULL;
3871 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3872 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003873#ifdef WLAN_OPEN_SOURCE
3874 struct timespec ts;
3875#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003876
3877 ENTER();
3878
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003879 if (!mgmt)
3880 return NULL;
3881
Jeff Johnson295189b2012-06-20 16:38:30 -07003882 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003883
3884#ifdef WLAN_OPEN_SOURCE
3885 /* Android does not want the timestamp from the frame.
3886 Instead it wants a monotonic increasing value */
3887 get_monotonic_boottime(&ts);
3888 mgmt->u.probe_resp.timestamp =
3889 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3890#else
3891 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003892 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3893 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003894
3895#endif
3896
Jeff Johnson295189b2012-06-20 16:38:30 -07003897 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3898 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003899
3900#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3901 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3902 /* Assuming this is the last IE, copy at the end */
3903 ie_length -=sizeof(qcom_ie_age);
3904 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3905 qie_age->element_id = QCOM_VENDOR_IE_ID;
3906 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3907 qie_age->oui_1 = QCOM_OUI1;
3908 qie_age->oui_2 = QCOM_OUI2;
3909 qie_age->oui_3 = QCOM_OUI3;
3910 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3911 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3912#endif
3913
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303915 if (bss_desc->fProbeRsp)
3916 {
3917 mgmt->frame_control |=
3918 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3919 }
3920 else
3921 {
3922 mgmt->frame_control |=
3923 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003925
3926#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303927 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3929 {
3930 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3931 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3934
3935 {
3936 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3937 }
3938 else
3939 {
3940 kfree(mgmt);
3941 return NULL;
3942 }
3943#else
3944 freq = ieee80211_channel_to_frequency(chan_no);
3945#endif
3946 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003947 /*when the band is changed on the fly using the GUI, three things are done
3948 * 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)
3949 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3950 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3951 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3952 * and discards the channels correponding to previous band and calls back with zero bss results.
3953 * 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
3954 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3955 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3956 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3957 * So drop the bss and continue to next bss.
3958 */
3959 if(chan == NULL)
3960 {
3961 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003962 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003963 return NULL;
3964 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003965 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303966 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 * */
3968 if (( eConnectionState_Associated ==
3969 pAdapter->sessionCtx.station.conn_info.connState ) &&
3970 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3971 pAdapter->sessionCtx.station.conn_info.bssId,
3972 WNI_CFG_BSSID_LEN)))
3973 {
3974 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3975 rssi = (pAdapter->rssi * 100);
3976 }
3977 else
3978 {
3979 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3980 }
3981
3982 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3983 frame_len, rssi, GFP_KERNEL);
3984 kfree(mgmt);
3985 return bss_status;
3986}
3987
3988/*
3989 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3990 * This function is used to update the BSS data base of CFG8011
3991 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303992struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 tCsrRoamInfo *pRoamInfo
3994 )
3995{
3996 tCsrRoamConnectedProfile roamProfile;
3997 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3998 struct cfg80211_bss *bss = NULL;
3999
4000 ENTER();
4001
4002 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4003 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4004
4005 if (NULL != roamProfile.pBssDesc)
4006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 &roamProfile);
4009
4010 if (NULL == bss)
4011 {
4012 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4013 __func__);
4014 }
4015
4016 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4017 }
4018 else
4019 {
4020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4021 __func__);
4022 }
4023 return bss;
4024}
4025
4026/*
4027 * FUNCTION: wlan_hdd_cfg80211_update_bss
4028 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304029static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4030 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004031 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304032{
Jeff Johnson295189b2012-06-20 16:38:30 -07004033 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4034 tCsrScanResultInfo *pScanResult;
4035 eHalStatus status = 0;
4036 tScanResultHandle pResult;
4037 struct cfg80211_bss *bss_status = NULL;
4038
4039 ENTER();
4040
4041 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4042 {
4043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4044 return -EAGAIN;
4045 }
4046
4047 /*
4048 * start getting scan results and populate cgf80211 BSS database
4049 */
4050 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4051
4052 /* no scan results */
4053 if (NULL == pResult)
4054 {
4055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4056 return status;
4057 }
4058
4059 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4060
4061 while (pScanResult)
4062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304063 /*
4064 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4065 * entry already exists in bss data base of cfg80211 for that
4066 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4067 * bss entry instead of cfg80211_inform_bss, But this call expects
4068 * mgmt packet as input. As of now there is no possibility to get
4069 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 * ieee80211_mgmt(probe response) and passing to c
4071 * fg80211_inform_bss_frame.
4072 * */
4073
4074 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4075 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304076
Jeff Johnson295189b2012-06-20 16:38:30 -07004077
4078 if (NULL == bss_status)
4079 {
4080 hddLog(VOS_TRACE_LEVEL_INFO,
4081 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4082 }
4083 else
4084 {
4085 cfg80211_put_bss(bss_status);
4086 }
4087
4088 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4089 }
4090
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304091 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004092
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304093 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004094}
4095
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004096void
4097hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4098{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304099 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004100 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4101 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4102 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004103} /****** end hddPrintMacAddr() ******/
4104
4105void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004106hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004107{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304108 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004109 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4110 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4111 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4112 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004113} /****** end hddPrintPmkId() ******/
4114
4115//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4116//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4117
4118//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4119//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4120
4121#define dump_bssid(bssid) \
4122 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004123 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4124 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4125 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004126 }
4127
4128#define dump_pmkid(pMac, pmkid) \
4129 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004130 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4131 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4132 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004133 }
4134
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004135#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004136/*
4137 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4138 * This function is used to notify the supplicant of a new PMKSA candidate.
4139 */
4140int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304141 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004142 int index, bool preauth )
4143{
Jeff Johnsone7245742012-09-05 17:12:55 -07004144#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004145 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004146 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004147
4148 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004149 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004150
4151 if( NULL == pRoamInfo )
4152 {
4153 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4154 return -EINVAL;
4155 }
4156
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004157 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4158 {
4159 dump_bssid(pRoamInfo->bssid);
4160 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004161 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004162 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004163#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304164 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004165}
4166#endif //FEATURE_WLAN_LFR
4167
Jeff Johnson295189b2012-06-20 16:38:30 -07004168/*
4169 * FUNCTION: hdd_cfg80211_scan_done_callback
4170 * scanning callback function, called after finishing scan
4171 *
4172 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304173static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4175{
4176 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304177 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004179 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4180 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 struct cfg80211_scan_request *req = NULL;
4182 int ret = 0;
4183
4184 ENTER();
4185
4186 hddLog(VOS_TRACE_LEVEL_INFO,
4187 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304188 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004189 __func__, halHandle, pContext, (int) scanId, (int) status);
4190
4191 //Block on scan req completion variable. Can't wait forever though.
4192 ret = wait_for_completion_interruptible_timeout(
4193 &pScanInfo->scan_req_completion_event,
4194 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4195 if (!ret)
4196 {
4197 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004198 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004199 }
4200
4201 if(pScanInfo->mScanPending != VOS_TRUE)
4202 {
4203 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004204 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 }
4206
4207 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 {
4210 hddLog(VOS_TRACE_LEVEL_INFO,
4211 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304212 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 (int) scanId);
4214 }
4215
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004217 pAdapter);
4218
4219 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304220 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004221
4222
4223 /* If any client wait scan result through WEXT
4224 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004225 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004226 {
4227 /* The other scan request waiting for current scan finish
4228 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004229 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004231 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004232 }
4233 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004234 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 {
4236 struct net_device *dev = pAdapter->dev;
4237 union iwreq_data wrqu;
4238 int we_event;
4239 char *msg;
4240
4241 memset(&wrqu, '\0', sizeof(wrqu));
4242 we_event = SIOCGIWSCAN;
4243 msg = NULL;
4244 wireless_send_event(dev, we_event, &wrqu, msg);
4245 }
4246 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004247 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004248
4249 /* Get the Scan Req */
4250 req = pAdapter->request;
4251
4252 if (!req)
4253 {
4254 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004255 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004256 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004257 }
4258
4259 /*
4260 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304261 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 req->n_ssids = 0;
4263 req->n_channels = 0;
4264 req->ie = 0;
4265
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004267 /* Scan is no longer pending */
4268 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004270 /*
4271 * cfg80211_scan_done informing NL80211 about completion
4272 * of scanning
4273 */
4274 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004275 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004276
Jeff Johnsone7245742012-09-05 17:12:55 -07004277allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004278 /* release the wake lock at the end of the scan*/
4279 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004280
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004281 /* Acquire wakelock to handle the case where APP's tries to suspend
4282 * immediatly after the driver gets connect request(i.e after scan)
4283 * from supplicant, this result in app's is suspending and not able
4284 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004285 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004286
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004287#ifdef FEATURE_WLAN_TDLS
4288 wlan_hdd_tdls_scan_done_callback(pAdapter);
4289#endif
4290
Jeff Johnson295189b2012-06-20 16:38:30 -07004291 EXIT();
4292 return 0;
4293}
4294
4295/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004296 * FUNCTION: hdd_isScanAllowed
4297 * Go through each adapter and check if scan allowed
4298 *
4299 */
4300v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4301{
4302 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4303 hdd_station_ctx_t *pHddStaCtx = NULL;
4304 hdd_adapter_t *pAdapter = NULL;
4305 VOS_STATUS status = 0;
4306 v_U8_t staId = 0;
4307 v_U8_t *staMac = NULL;
4308
4309 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4310
4311 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4312 {
4313 pAdapter = pAdapterNode->pAdapter;
4314
4315 if( pAdapter )
4316 {
4317 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304318 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004319 __func__, pAdapter->device_mode);
4320 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4321 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4322 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4323 {
4324 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4325 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4326 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4327 {
4328 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4329 hddLog(VOS_TRACE_LEVEL_ERROR,
4330 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304331 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004332 staMac[0], staMac[1], staMac[2],
4333 staMac[3], staMac[4], staMac[5]);
4334 return VOS_FALSE;
4335 }
4336 }
4337 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4338 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4339 {
4340 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004343 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4344 {
4345 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4346
4347 hddLog(VOS_TRACE_LEVEL_ERROR,
4348 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304349 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004350 staMac[0], staMac[1], staMac[2],
4351 staMac[3], staMac[4], staMac[5]);
4352 return VOS_FALSE;
4353 }
4354 }
4355 }
4356 }
4357 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4358 pAdapterNode = pNext;
4359 }
4360 hddLog(VOS_TRACE_LEVEL_INFO,
4361 "%s: Scan allowed", __func__);
4362 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304363}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004364
4365/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004366 * FUNCTION: wlan_hdd_cfg80211_scan
4367 * this scan respond to scan trigger and update cfg80211 scan database
4368 * later, scan dump command can be used to recieve scan results
4369 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004370int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4371#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4372 struct net_device *dev,
4373#endif
4374 struct cfg80211_scan_request *request)
4375{
4376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4377 struct net_device *dev = request->wdev->netdev;
4378#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004380 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4381 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304382 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 tCsrScanRequest scanRequest;
4384 tANI_U8 *channelList = NULL, i;
4385 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304386 int status;
4387 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004388 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004389
4390 ENTER();
4391
4392 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4393 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004394
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304395 status = wlan_hdd_validate_context(pHddCtx);
4396
4397 if (0 != status)
4398 {
4399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4400 "%s: HDD context is not valid", __func__);
4401 return status;
4402 }
4403
4404 cfg_param = pHddCtx->cfg_ini;
4405 pScanInfo = &pHddCtx->scan_info;
4406
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004407 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004408 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004409 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004410 {
4411 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004412 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4413 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414 return -EBUSY;
4415 }
4416
Jeff Johnson295189b2012-06-20 16:38:30 -07004417#ifdef WLAN_BTAMP_FEATURE
4418 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004419 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004420 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004421 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 "%s: No scanning when AMP is on", __func__);
4423 return -EOPNOTSUPP;
4424 }
4425#endif
4426 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004427 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004428 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004429 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 "%s: Not scanning on device_mode = %d",
4431 __func__, pAdapter->device_mode);
4432 return -EOPNOTSUPP;
4433 }
4434
4435 if (TRUE == pScanInfo->mScanPending)
4436 {
4437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004438 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 }
4440
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304441 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004442 //Channel and action frame is pending
4443 //Otherwise Cancel Remain On Channel and allow Scan
4444 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004445 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004446 {
4447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4448 return -EBUSY;
4449 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004450#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004451 /* if tdls disagree scan right now, return immediately.
4452 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4453 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4454 */
4455 status = wlan_hdd_tdls_scan_callback (pAdapter,
4456 wiphy,
4457#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4458 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004459#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004460 request);
4461 if(status <= 0)
4462 {
4463 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4464 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004465 }
4466#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004467
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4469 {
4470 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004471 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004472 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004474 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4475 {
4476 hddLog(VOS_TRACE_LEVEL_WARN,
4477 "%s: MAX TM Level Scan not allowed", __func__);
4478 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304479 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 }
4481 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4482
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004483 /* Check if scan is allowed at this point of time.
4484 */
4485 if (!hdd_isScanAllowed(pHddCtx))
4486 {
4487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4488 return -EBUSY;
4489 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304490
Jeff Johnson295189b2012-06-20 16:38:30 -07004491 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4492
4493 if (NULL != request)
4494 {
4495 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304496 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004497
4498 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4499 * Becasue of this, driver is assuming that this is not wildcard scan and so
4500 * is not aging out the scan results.
4501 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004502 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004503 {
4504 request->n_ssids = 0;
4505 }
4506
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004507 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004508 {
4509 tCsrSSIDInfo *SsidInfo;
4510 int j;
4511 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4512 /* Allocate num_ssid tCsrSSIDInfo structure */
4513 SsidInfo = scanRequest.SSIDs.SSIDList =
4514 ( tCsrSSIDInfo *)vos_mem_malloc(
4515 request->n_ssids*sizeof(tCsrSSIDInfo));
4516
4517 if(NULL == scanRequest.SSIDs.SSIDList)
4518 {
4519 hddLog(VOS_TRACE_LEVEL_ERROR,
4520 "memory alloc failed SSIDInfo buffer");
4521 return -ENOMEM;
4522 }
4523
4524 /* copy all the ssid's and their length */
4525 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4526 {
4527 /* get the ssid length */
4528 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4529 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4530 SsidInfo->SSID.length);
4531 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4532 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4533 j, SsidInfo->SSID.ssId);
4534 }
4535 /* set the scan type to active */
4536 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4537 }
4538 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4539 {
4540 /* set the scan type to active */
4541 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4542 }
4543 else
4544 {
4545 /*Set the scan type to default type, in this case it is ACTIVE*/
4546 scanRequest.scanType = pScanInfo->scan_mode;
4547 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304548 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4550 }
4551 else
4552 {
4553 /* set the scan type to active */
4554 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4555 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4556
4557 /* set min and max channel time to zero */
4558 scanRequest.minChnTime = 0;
4559 scanRequest.maxChnTime = 0;
4560 }
4561
4562 /* set BSSType to default type */
4563 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4564
4565 /*TODO: scan the requested channels only*/
4566
4567 /*Right now scanning all the channels */
4568 if( request )
4569 {
4570 if( request->n_channels )
4571 {
4572 channelList = vos_mem_malloc( request->n_channels );
4573 if( NULL == channelList )
4574 {
4575 status = -ENOMEM;
4576 goto free_mem;
4577 }
4578
4579 for( i = 0 ; i < request->n_channels ; i++ )
4580 channelList[i] = request->channels[i]->hw_value;
4581 }
4582
4583 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4584 scanRequest.ChannelInfo.ChannelList = channelList;
4585
4586 /* set requestType to full scan */
4587 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588
4589 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004590 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304591 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004592 */
4593
4594 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304595 * and in that case driver shoudnt flush scan results. If
4596 * driver flushes the scan results here and unfortunately if
4597 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004598 * fails which is not desired
4599 */
4600
4601 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4602 {
4603 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4604 pAdapter->sessionId );
4605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004606
4607 if( request->ie_len )
4608 {
4609 /* save this for future association (join requires this) */
4610 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4611 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4612 pScanInfo->scanAddIE.length = request->ie_len;
4613
4614 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004615 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4616 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004617 )
4618 {
4619 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4620 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4621 }
4622
4623 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4624 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4625
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4627 request->ie_len);
4628 if (pP2pIe != NULL)
4629 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004630#ifdef WLAN_FEATURE_P2P_DEBUG
4631 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4632 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4633 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4634 {
4635 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4636 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4637 "Go nego completed to Connection is started");
4638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4639 "for 8way Handshake");
4640 }
4641 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4642 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4643 {
4644 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4645 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4646 "Disconnected state to Connection is started");
4647 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4648 "for 4way Handshake");
4649 }
4650#endif
4651
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 /* no_cck will be set during p2p find to disable 11b rates */
4653 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 hddLog(VOS_TRACE_LEVEL_INFO,
4656 "%s: This is a P2P Search", __func__);
4657 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004658
Jeff Johnsone7245742012-09-05 17:12:55 -07004659 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4660 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004661 /* set requestType to P2P Discovery */
4662 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004663 }
4664
4665 /*
4666 Skip Dfs Channel in case of P2P Search
4667 if it is set in ini file
4668 */
4669 if(cfg_param->skipDfsChnlInP2pSearch)
4670 {
4671 scanRequest.skipDfsChnlInP2pSearch = 1;
4672 }
4673 else
4674 {
4675 scanRequest.skipDfsChnlInP2pSearch = 0;
4676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004677
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 }
4679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004680 }
4681 }
4682
4683 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4684
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004685 /* acquire the wakelock to avoid the apps suspend during the scan. To
4686 * address the following issues.
4687 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4688 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4689 * for long time, this result in apps running at full power for long time.
4690 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4691 * be stuck in full power because of resume BMPS
4692 */
4693 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004694
4695 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004696 pAdapter->sessionId, &scanRequest, &scanId,
4697 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004698
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 if (eHAL_STATUS_SUCCESS != status)
4700 {
4701 hddLog(VOS_TRACE_LEVEL_ERROR,
4702 "%s: sme_ScanRequest returned error %d", __func__, status);
4703 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004704 if(eHAL_STATUS_RESOURCES == status)
4705 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004706 hddLog(VOS_TRACE_LEVEL_INFO, "%s: HO is in progress.So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004707 status = -EBUSY;
4708 } else {
4709 status = -EIO;
4710 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004711 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004712 goto free_mem;
4713 }
4714
4715 pScanInfo->mScanPending = TRUE;
4716 pAdapter->request = request;
4717 pScanInfo->scanId = scanId;
4718
4719 complete(&pScanInfo->scan_req_completion_event);
4720
4721free_mem:
4722 if( scanRequest.SSIDs.SSIDList )
4723 {
4724 vos_mem_free(scanRequest.SSIDs.SSIDList);
4725 }
4726
4727 if( channelList )
4728 vos_mem_free( channelList );
4729
4730 EXIT();
4731
4732 return status;
4733}
4734
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004735
4736void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4737{
4738 v_U8_t iniDot11Mode =
4739 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4740 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4741
4742 switch ( iniDot11Mode )
4743 {
4744 case eHDD_DOT11_MODE_AUTO:
4745 case eHDD_DOT11_MODE_11ac:
4746 case eHDD_DOT11_MODE_11ac_ONLY:
4747#ifdef WLAN_FEATURE_11AC
4748 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4749#else
4750 hddDot11Mode = eHDD_DOT11_MODE_11n;
4751#endif
4752 break;
4753 case eHDD_DOT11_MODE_11n:
4754 case eHDD_DOT11_MODE_11n_ONLY:
4755 hddDot11Mode = eHDD_DOT11_MODE_11n;
4756 break;
4757 default:
4758 hddDot11Mode = iniDot11Mode;
4759 break;
4760 }
4761 /* This call decides required channel bonding mode */
4762 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4763 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4764 operationChannel);
4765}
4766
Jeff Johnson295189b2012-06-20 16:38:30 -07004767/*
4768 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304769 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304771int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004772 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004773{
4774 int status = 0;
4775 hdd_wext_state_t *pWextState;
4776 v_U32_t roamId;
4777 tCsrRoamProfile *pRoamProfile;
4778 eMib_dot11DesiredBssType connectedBssType;
4779 eCsrAuthType RSNAuthType;
4780
4781 ENTER();
4782
4783 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304784
Jeff Johnson295189b2012-06-20 16:38:30 -07004785 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4786 {
4787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4788 return -EINVAL;
4789 }
4790
4791 pRoamProfile = &pWextState->roamProfile;
4792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304793 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004795 int ret = 0;
4796 hdd_station_ctx_t *pHddStaCtx;
4797 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4798 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4799
4800 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4801 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4802 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004803 {
4804 /* Issue disconnect to CSR */
4805 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304806 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4808 pAdapter->sessionId,
4809 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4810 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004811 ret = wait_for_completion_interruptible_timeout(
4812 &pAdapter->disconnect_comp_var,
4813 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4814 if (0 == ret)
4815 {
4816 VOS_ASSERT(0);
4817 }
4818 }
4819 }
4820 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4821 {
4822 ret = wait_for_completion_interruptible_timeout(
4823 &pAdapter->disconnect_comp_var,
4824 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4825 if (0 == ret)
4826 {
4827 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004828 }
4829 }
4830
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304831 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4833 {
4834 /*QoS not enabled in cfg file*/
4835 pRoamProfile->uapsd_mask = 0;
4836 }
4837 else
4838 {
4839 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4842 }
4843
4844 pRoamProfile->SSIDs.numOfSSIDs = 1;
4845 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4846 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304847 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4849 ssid, ssid_len);
4850
4851 if (bssid)
4852 {
4853 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4854 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4855 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304856 /* Save BSSID in seperate variable as well, as RoamProfile
4857 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004858 case of join failure we should send valid BSSID to supplicant
4859 */
4860 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4861 WNI_CFG_BSSID_LEN);
4862 }
4863
4864 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4865 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304866 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 /*set gen ie*/
4868 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4869 /*set auth*/
4870 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004872#ifdef FEATURE_WLAN_WAPI
4873 if (pAdapter->wapi_info.nWapiMode)
4874 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004875 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004876 switch (pAdapter->wapi_info.wapiAuthMode)
4877 {
4878 case WAPI_AUTH_MODE_PSK:
4879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004880 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 pAdapter->wapi_info.wapiAuthMode);
4882 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4883 break;
4884 }
4885 case WAPI_AUTH_MODE_CERT:
4886 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004887 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004888 pAdapter->wapi_info.wapiAuthMode);
4889 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4890 break;
4891 }
4892 } // End of switch
4893 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4894 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4895 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004896 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004897 pRoamProfile->AuthType.numEntries = 1;
4898 pRoamProfile->EncryptionType.numEntries = 1;
4899 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4900 pRoamProfile->mcEncryptionType.numEntries = 1;
4901 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4902 }
4903 }
4904#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304905#ifdef WLAN_FEATURE_GTK_OFFLOAD
4906 /* Initializing gtkOffloadRequestParams */
4907 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4908 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4909 {
4910 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4911 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4912 0, sizeof (tSirGtkOffloadParams));
4913 }
4914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004915 pRoamProfile->csrPersona = pAdapter->device_mode;
4916
Jeff Johnson32d95a32012-09-10 13:15:23 -07004917 if( operatingChannel )
4918 {
4919 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4920 pRoamProfile->ChannelInfo.numOfChannels = 1;
4921 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004922 else
4923 {
4924 pRoamProfile->ChannelInfo.ChannelList = NULL;
4925 pRoamProfile->ChannelInfo.numOfChannels = 0;
4926 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004927 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4928 {
4929 hdd_select_cbmode(pAdapter,operatingChannel);
4930 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004931 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4932 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304933 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004934 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004935 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4936 */
4937 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4938 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4939 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304940
4941 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004942 pAdapter->sessionId, pRoamProfile, &roamId);
4943
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004944 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304945 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4946
4947 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4949 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4950 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304951 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004952 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304953 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004954
4955 pRoamProfile->ChannelInfo.ChannelList = NULL;
4956 pRoamProfile->ChannelInfo.numOfChannels = 0;
4957
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 }
4959 else
4960 {
4961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4962 return -EINVAL;
4963 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004964 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004965 return status;
4966}
4967
4968/*
4969 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4970 * This function is used to set the authentication type (OPEN/SHARED).
4971 *
4972 */
4973static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4974 enum nl80211_auth_type auth_type)
4975{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304976 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4978
4979 ENTER();
4980
4981 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304982 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004984 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304985 hddLog(VOS_TRACE_LEVEL_INFO,
4986 "%s: set authentication type to AUTOSWITCH", __func__);
4987 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4988 break;
4989
4990 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004991#ifdef WLAN_FEATURE_VOWIFI_11R
4992 case NL80211_AUTHTYPE_FT:
4993#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304994 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 "%s: set authentication type to OPEN", __func__);
4996 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4997 break;
4998
4999 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305000 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005001 "%s: set authentication type to SHARED", __func__);
5002 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5003 break;
5004#ifdef FEATURE_WLAN_CCX
5005 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305006 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 "%s: set authentication type to CCKM WPA", __func__);
5008 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5009 break;
5010#endif
5011
5012
5013 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 hddLog(VOS_TRACE_LEVEL_ERROR,
5015 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 auth_type);
5017 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5018 return -EINVAL;
5019 }
5020
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 pHddStaCtx->conn_info.authType;
5023 return 0;
5024}
5025
5026/*
5027 * FUNCTION: wlan_hdd_set_akm_suite
5028 * This function is used to set the key mgmt type(PSK/8021x).
5029 *
5030 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305031static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005032 u32 key_mgmt
5033 )
5034{
5035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5036 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305037
Jeff Johnson295189b2012-06-20 16:38:30 -07005038 /*set key mgmt type*/
5039 switch(key_mgmt)
5040 {
5041 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305042#ifdef WLAN_FEATURE_VOWIFI_11R
5043 case WLAN_AKM_SUITE_FT_PSK:
5044#endif
5045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 __func__);
5047 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5048 break;
5049
5050 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305051#ifdef WLAN_FEATURE_VOWIFI_11R
5052 case WLAN_AKM_SUITE_FT_8021X:
5053#endif
5054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 __func__);
5056 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5057 break;
5058#ifdef FEATURE_WLAN_CCX
5059#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5060#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5061 case WLAN_AKM_SUITE_CCKM:
5062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5063 __func__);
5064 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5065 break;
5066#endif
5067
5068 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 __func__, key_mgmt);
5071 return -EINVAL;
5072
5073 }
5074 return 0;
5075}
5076
5077/*
5078 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 * (NONE/WEP40/WEP104/TKIP/CCMP).
5081 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305082static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5083 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 bool ucast
5085 )
5086{
5087 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305088 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5090
5091 ENTER();
5092
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305093 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 __func__, cipher);
5097 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5098 }
5099 else
5100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305101
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305103 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 {
5105 case IW_AUTH_CIPHER_NONE:
5106 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5107 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305108
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305110 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005111 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305112
Jeff Johnson295189b2012-06-20 16:38:30 -07005113 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305114 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005115 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305116
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 case WLAN_CIPHER_SUITE_TKIP:
5118 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5119 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305120
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 case WLAN_CIPHER_SUITE_CCMP:
5122 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5123 break;
5124#ifdef FEATURE_WLAN_WAPI
5125 case WLAN_CIPHER_SUITE_SMS4:
5126 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5127 break;
5128#endif
5129
5130#ifdef FEATURE_WLAN_CCX
5131 case WLAN_CIPHER_SUITE_KRK:
5132 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5133 break;
5134#endif
5135 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 __func__, cipher);
5138 return -EOPNOTSUPP;
5139 }
5140 }
5141
5142 if (ucast)
5143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305144 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 __func__, encryptionType);
5146 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5147 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305148 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005149 encryptionType;
5150 }
5151 else
5152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005154 __func__, encryptionType);
5155 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5156 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5157 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5158 }
5159
5160 return 0;
5161}
5162
5163
5164/*
5165 * FUNCTION: wlan_hdd_cfg80211_set_ie
5166 * This function is used to parse WPA/RSN IE's.
5167 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305168int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5169 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005170 size_t ie_len
5171 )
5172{
5173 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5174 u8 *genie = ie;
5175 v_U16_t remLen = ie_len;
5176#ifdef FEATURE_WLAN_WAPI
5177 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5178 u16 *tmp;
5179 v_U16_t akmsuiteCount;
5180 int *akmlist;
5181#endif
5182 ENTER();
5183
5184 /* clear previous assocAddIE */
5185 pWextState->assocAddIE.length = 0;
5186 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5187
5188 while (remLen >= 2)
5189 {
5190 v_U16_t eLen = 0;
5191 v_U8_t elementId;
5192 elementId = *genie++;
5193 eLen = *genie++;
5194 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305195
5196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005197 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305198
5199 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005202 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 -07005203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 "%s: Invalid WPA IE", __func__);
5206 return -EINVAL;
5207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305208 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 {
5210 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305211 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005212 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305213
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5215 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005216 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5217 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005218 VOS_ASSERT(0);
5219 return -ENOMEM;
5220 }
5221 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5222 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5223 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305224
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5226 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5227 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5228 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305229 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5230 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5232 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5233 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5234 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5235 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305237 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5238 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 /*Consider P2P IE, only for P2P Client */
5240 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5241 {
5242 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305243 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005244 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305245
Jeff Johnson295189b2012-06-20 16:38:30 -07005246 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5247 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005248 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5249 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005250 VOS_ASSERT(0);
5251 return -ENOMEM;
5252 }
5253 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5254 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5255 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5258 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005260#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305261 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5262 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 /*Consider WFD IE, only for P2P Client */
5264 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5265 {
5266 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305267 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5271 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005272 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5273 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005274 VOS_ASSERT(0);
5275 return -ENOMEM;
5276 }
5277 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5278 // WPS IE + P2P IE + WFD IE
5279 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5280 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305281
Jeff Johnson295189b2012-06-20 16:38:30 -07005282 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5283 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5284 }
5285#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005286 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305287 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005288 HS20_OUI_TYPE_SIZE)) )
5289 {
5290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005292 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005293
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005294 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5295 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5297 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005298 VOS_ASSERT(0);
5299 return -ENOMEM;
5300 }
5301 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5302 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005303
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005304 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5305 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5306 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005307
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 break;
5309 case DOT11F_EID_RSN:
5310 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5311 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5312 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5313 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5314 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5315 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005316 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5317 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305318 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005319 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305320 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005321 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305322
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005323 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5324 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005325 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5326 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005327 VOS_ASSERT(0);
5328 return -ENOMEM;
5329 }
5330 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5331 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305332
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005333 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5334 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5335 break;
5336 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005337#ifdef FEATURE_WLAN_WAPI
5338 case WLAN_EID_WAPI:
5339 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5340 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5341 pAdapter->wapi_info.nWapiMode);
5342 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305343 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 akmsuiteCount = WPA_GET_LE16(tmp);
5345 tmp = tmp + 1;
5346 akmlist = (int *)(tmp);
5347 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5348 {
5349 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5350 }
5351 else
5352 {
5353 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5354 VOS_ASSERT(0);
5355 return -EINVAL;
5356 }
5357
5358 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5359 {
5360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005361 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305365 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005367 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5369 }
5370 break;
5371#endif
5372 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305373 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005375 /* when Unknown IE is received we should break and continue
5376 * to the next IE in the buffer instead we were returning
5377 * so changing this to break */
5378 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 }
5380 genie += eLen;
5381 remLen -= eLen;
5382 }
5383 EXIT();
5384 return 0;
5385}
5386
5387/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305388 * FUNCTION: hdd_isWPAIEPresent
5389 * Parse the received IE to find the WPA IE
5390 *
5391 */
5392static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5393{
5394 v_U8_t eLen = 0;
5395 v_U16_t remLen = ie_len;
5396 v_U8_t elementId = 0;
5397
5398 while (remLen >= 2)
5399 {
5400 elementId = *ie++;
5401 eLen = *ie++;
5402 remLen -= 2;
5403 if (eLen > remLen)
5404 {
5405 hddLog(VOS_TRACE_LEVEL_ERROR,
5406 "%s: IE length is wrong %d", __func__, eLen);
5407 return FALSE;
5408 }
5409 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5410 {
5411 /* OUI - 0x00 0X50 0XF2
5412 WPA Information Element - 0x01
5413 WPA version - 0x01*/
5414 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5415 return TRUE;
5416 }
5417 ie += eLen;
5418 remLen -= eLen;
5419 }
5420 return FALSE;
5421}
5422
5423/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305425 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 * parameters during connect operation.
5427 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305428int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 struct cfg80211_connect_params *req
5430 )
5431{
5432 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305433 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 ENTER();
5435
5436 /*set wpa version*/
5437 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5438
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305439 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 {
5441 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305442 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305443 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305445 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 * since p2p ie is also put in same buffer.
5447 * */
5448 {
5449 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5450 }
5451 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5452 {
5453 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5454 }
5455 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305456
5457 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 pWextState->wpaVersion);
5459
5460 /*set authentication type*/
5461 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5462
5463 if (0 > status)
5464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 "%s: failed to set authentication type ", __func__);
5467 return status;
5468 }
5469
5470 /*set key mgmt type*/
5471 if (req->crypto.n_akm_suites)
5472 {
5473 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5474 if (0 > status)
5475 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 __func__);
5478 return status;
5479 }
5480 }
5481
5482 /*set pairwise cipher type*/
5483 if (req->crypto.n_ciphers_pairwise)
5484 {
5485 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5486 req->crypto.ciphers_pairwise[0], true);
5487 if (0 > status)
5488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305489 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 "%s: failed to set unicast cipher type", __func__);
5491 return status;
5492 }
5493 }
5494 else
5495 {
5496 /*Reset previous cipher suite to none*/
5497 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5498 if (0 > status)
5499 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305500 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 "%s: failed to set unicast cipher type", __func__);
5502 return status;
5503 }
5504 }
5505
5506 /*set group cipher type*/
5507 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5508 false);
5509
5510 if (0 > status)
5511 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 __func__);
5514 return status;
5515 }
5516
Chet Lanctot186b5732013-03-18 10:26:30 -07005517#ifdef WLAN_FEATURE_11W
5518 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5519#endif
5520
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5522 if (req->ie_len)
5523 {
5524 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5525 if ( 0 > status)
5526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 __func__);
5529 return status;
5530 }
5531 }
5532
5533 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305534 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 {
5536 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5537 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5538 )
5539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305540 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 __func__);
5545 return -EOPNOTSUPP;
5546 }
5547 else
5548 {
5549 u8 key_len = req->key_len;
5550 u8 key_idx = req->key_idx;
5551
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305552 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 && (CSR_MAX_NUM_KEY > key_idx)
5554 )
5555 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305556 hddLog(VOS_TRACE_LEVEL_INFO,
5557 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 __func__, key_idx, key_len);
5559 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305560 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305562 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 (u8)key_len;
5564 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5565 }
5566 }
5567 }
5568 }
5569
5570 return status;
5571}
5572
5573/*
5574 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305575 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 * parameters during connect operation.
5577 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305578static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 struct net_device *ndev,
5580 struct cfg80211_connect_params *req
5581 )
5582{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305583 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005585 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5586 hdd_context_t *pHddCtx = NULL;
5587
5588 ENTER();
5589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305590 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5592
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305593 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5594 status = wlan_hdd_validate_context(pHddCtx);
5595
5596 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5599 "%s: HDD context is not valid", __func__);
5600 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 }
5602
5603#ifdef WLAN_BTAMP_FEATURE
5604 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305605 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305607 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005609 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 }
5611#endif
5612 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305613 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005614
5615 if ( 0 > status)
5616 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 __func__);
5619 return status;
5620 }
5621
5622 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005623 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5625 (vos_concurrent_sessions_running()))
5626 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305627 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 }
5629
Mohit Khanna765234a2012-09-11 15:08:35 -07005630 if ( req->channel )
5631 {
5632 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5633 req->ssid_len, req->bssid,
5634 req->channel->hw_value);
5635 }
5636 else
5637 {
5638 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305639 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005640 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005641
5642 if (0 > status)
5643 {
5644 //ReEnable BMPS if disabled
5645 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5646 (NULL != pHddCtx))
5647 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305648 if (pHddCtx->hdd_wlan_suspended)
5649 {
5650 hdd_set_pwrparams(pHddCtx);
5651 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 //ReEnable Bmps and Imps back
5653 hdd_enable_bmps_imps(pHddCtx);
5654 }
5655
5656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5657 return status;
5658 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305659 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 EXIT();
5661 return status;
5662}
5663
5664
5665/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305666 * FUNCTION: wlan_hdd_disconnect
5667 * This function is used to issue a disconnect request to SME
5668 */
5669int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5670{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305671 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305672 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305673 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5674
5675 status = wlan_hdd_validate_context(pHddCtx);
5676
5677 if (0 != status)
5678 {
5679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5680 "%s: HDD context is not valid", __func__);
5681 return status;
5682 }
5683
5684 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305685 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305686 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305687
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305688 /*issue disconnect*/
5689 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5690 pAdapter->sessionId, reason);
5691
5692 if ( 0 != status )
5693 {
5694 hddLog(VOS_TRACE_LEVEL_ERROR,
5695 "%s csrRoamDisconnect failure, returned %d \n",
5696 __func__, (int)status );
5697 return -EINVAL;
5698 }
5699 wait_for_completion_interruptible_timeout(
5700 &pAdapter->disconnect_comp_var,
5701 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5702 /*stop tx queues*/
5703 netif_tx_disable(pAdapter->dev);
5704 netif_carrier_off(pAdapter->dev);
5705 return status;
5706}
5707
5708
5709/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 * FUNCTION: wlan_hdd_cfg80211_disconnect
5711 * This function is used to issue a disconnect request to SME
5712 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305713static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 struct net_device *dev,
5715 u16 reason
5716 )
5717{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5719 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305721 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005723 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305724#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005725 tANI_U8 staIdx;
5726#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305727
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305729
5730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 __func__,pAdapter->device_mode);
5732
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5734 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005735
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305736 status = wlan_hdd_validate_context(pHddCtx);
5737
5738 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005739 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5741 "%s: HDD context is not valid", __func__);
5742 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305744
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 if (NULL != pRoamProfile)
5746 {
5747 /*issue disconnect request to SME, if station is in connected state*/
5748 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305750 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305752 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 switch(reason)
5754 {
5755 case WLAN_REASON_MIC_FAILURE:
5756 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5757 break;
5758
5759 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5760 case WLAN_REASON_DISASSOC_AP_BUSY:
5761 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5762 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5763 break;
5764
5765 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5766 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5767 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5768 break;
5769
5770 case WLAN_REASON_DEAUTH_LEAVING:
5771 default:
5772 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5773 break;
5774 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305775 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5776 pScanInfo = &pHddCtx->scan_info;
5777 if (pScanInfo->mScanPending)
5778 {
5779 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5780 "Aborting Scan");
5781 hdd_abort_mac_scan(pHddCtx);
5782 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005783
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005784#ifdef FEATURE_WLAN_TDLS
5785 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005786 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005787 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005788 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5789 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005790 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005791 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005792 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005793 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005794 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005795 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005796 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005797 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005798 pAdapter->sessionId,
5799 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005800 }
5801 }
5802#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305803 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5804 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 {
5806 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305807 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 __func__, (int)status );
5809 return -EINVAL;
5810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 }
5812 }
5813 else
5814 {
5815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5816 }
5817
5818 return status;
5819}
5820
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305821
Jeff Johnson295189b2012-06-20 16:38:30 -07005822/*
5823 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 * settings in IBSS mode.
5826 */
5827static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 struct cfg80211_ibss_params *params
5830 )
5831{
5832 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305836
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 ENTER();
5838
5839 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5840
5841 if (params->ie_len && ( NULL != params->ie) )
5842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305843 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 {
5845 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5846 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5847 }
5848 else
5849 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005850 tDot11fIEWPA dot11WPAIE;
5851 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5852
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005854 // Unpack the WPA IE
5855 //Skip past the EID byte and length byte - and four byte WiFi OUI
5856 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5857 &params->ie[2+4],
5858 params->ie[1] - 4,
5859 &dot11WPAIE);
5860 /*Extract the multicast cipher, the encType for unicast
5861 cipher for wpa-none is none*/
5862 encryptionType =
5863 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 }
5865 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5866
5867 if (0 > status)
5868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 __func__);
5871 return status;
5872 }
5873 }
5874
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305875 pWextState->roamProfile.AuthType.authType[0] =
5876 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5878
5879 if (params->privacy)
5880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881 /* Security enabled IBSS, At this time there is no information available
5882 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305884 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305886 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 *enable privacy bit in beacons */
5888
5889 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5890 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005891 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5892 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5894 pWextState->roamProfile.EncryptionType.numEntries = 1;
5895 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 return status;
5897}
5898
5899/*
5900 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305903static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 struct net_device *dev,
5905 struct cfg80211_ibss_params *params
5906 )
5907{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5910 tCsrRoamProfile *pRoamProfile;
5911 int status;
5912 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305913 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005914
5915 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305916
5917 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5919
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305920 status = wlan_hdd_validate_context(pHddCtx);
5921
5922 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5925 "%s: HDD context is not valid", __func__);
5926 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 }
5928
5929 if (NULL == pWextState)
5930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305931 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 __func__);
5933 return -EIO;
5934 }
5935
5936 pRoamProfile = &pWextState->roamProfile;
5937
5938 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305940 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 "%s Interface type is not set to IBSS \n", __func__);
5942 return -EINVAL;
5943 }
5944
5945 /* Set Channel */
5946 if (NULL != params->channel)
5947 {
5948 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005949 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5950 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5951 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5952 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005953
5954 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305955 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 ieee80211_frequency_to_channel(params->channel->center_freq);
5957
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005958
5959 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5960 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5963 __func__);
5964 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005966
5967 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005969 if (channelNum == validChan[indx])
5970 {
5971 break;
5972 }
5973 }
5974 if (indx >= numChans)
5975 {
5976 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 __func__, channelNum);
5978 return -EINVAL;
5979 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005980 /* Set the Operational Channel */
5981 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5982 channelNum);
5983 pRoamProfile->ChannelInfo.numOfChannels = 1;
5984 pHddStaCtx->conn_info.operationChannel = channelNum;
5985 pRoamProfile->ChannelInfo.ChannelList =
5986 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 }
5988
5989 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 if (status < 0)
5992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 __func__);
5995 return status;
5996 }
5997
5998 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305999 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006000 params->ssid_len, params->bssid,
6001 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006002
6003 if (0 > status)
6004 {
6005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6006 return status;
6007 }
6008
6009 return 0;
6010}
6011
6012/*
6013 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306014 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306016static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 struct net_device *dev
6018 )
6019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6022 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306023 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6024 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006025
6026 ENTER();
6027
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306028 status = wlan_hdd_validate_context(pHddCtx);
6029
6030 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006031 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6033 "%s: HDD context is not valid", __func__);
6034 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006035 }
6036
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6038 if (NULL == pWextState)
6039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306040 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 __func__);
6042 return -EIO;
6043 }
6044
6045 pRoamProfile = &pWextState->roamProfile;
6046
6047 /* Issue disconnect only if interface type is set to IBSS */
6048 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306050 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 __func__);
6052 return -EINVAL;
6053 }
6054
6055 /* Issue Disconnect request */
6056 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6057 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6058 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6059
6060 return 0;
6061}
6062
6063/*
6064 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6065 * This function is used to set the phy parameters
6066 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6067 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306068static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 u32 changed)
6070{
6071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6072 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306073 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006074
6075 ENTER();
6076
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306077 status = wlan_hdd_validate_context(pHddCtx);
6078
6079 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006080 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6082 "%s: HDD context is not valid", __func__);
6083 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006084 }
6085
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6087 {
6088 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6089 WNI_CFG_RTS_THRESHOLD_STAMAX :
6090 wiphy->rts_threshold;
6091
6092 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095 hddLog(VOS_TRACE_LEVEL_ERROR,
6096 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 __func__, rts_threshold);
6098 return -EINVAL;
6099 }
6100
6101 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6102 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306105 hddLog(VOS_TRACE_LEVEL_ERROR,
6106 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 __func__, rts_threshold);
6108 return -EIO;
6109 }
6110
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306111 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 rts_threshold);
6113 }
6114
6115 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6116 {
6117 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6118 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6119 wiphy->frag_threshold;
6120
6121 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306122 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 hddLog(VOS_TRACE_LEVEL_ERROR,
6125 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 frag_threshold);
6127 return -EINVAL;
6128 }
6129
6130 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6131 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306132 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306134 hddLog(VOS_TRACE_LEVEL_ERROR,
6135 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 __func__, frag_threshold);
6137 return -EIO;
6138 }
6139
6140 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6141 frag_threshold);
6142 }
6143
6144 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6145 || (changed & WIPHY_PARAM_RETRY_LONG))
6146 {
6147 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6148 wiphy->retry_short :
6149 wiphy->retry_long;
6150
6151 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6152 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 __func__, retry_value);
6156 return -EINVAL;
6157 }
6158
6159 if (changed & WIPHY_PARAM_RETRY_SHORT)
6160 {
6161 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6162 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306163 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306165 hddLog(VOS_TRACE_LEVEL_ERROR,
6166 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 __func__, retry_value);
6168 return -EIO;
6169 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306170 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 __func__, retry_value);
6172 }
6173 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6174 {
6175 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6176 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306177 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306179 hddLog(VOS_TRACE_LEVEL_ERROR,
6180 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 __func__, retry_value);
6182 return -EIO;
6183 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306184 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 __func__, retry_value);
6186 }
6187 }
6188
6189 return 0;
6190}
6191
6192/*
6193 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6194 * This function is used to set the txpower
6195 */
6196static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6197#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306198 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006199#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006201#endif
6202 int dbm)
6203{
6204 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306205 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6207 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306208 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006209
6210 ENTER();
6211
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306212 status = wlan_hdd_validate_context(pHddCtx);
6213
6214 if (0 != status)
6215 {
6216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6217 "%s: HDD context is not valid", __func__);
6218 return status;
6219 }
6220
6221 hHal = pHddCtx->hHal;
6222
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306223 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6224 dbm, ccmCfgSetCallback,
6225 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306227 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6229 return -EIO;
6230 }
6231
6232 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6233 dbm);
6234
6235 switch(type)
6236 {
6237 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6238 /* Fall through */
6239 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6240 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6241 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6243 __func__);
6244 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 }
6246 break;
6247 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 __func__);
6250 return -EOPNOTSUPP;
6251 break;
6252 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6254 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 return -EIO;
6256 }
6257
6258 return 0;
6259}
6260
6261/*
6262 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6263 * This function is used to read the txpower
6264 */
6265static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6266{
6267
6268 hdd_adapter_t *pAdapter;
6269 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306270 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006271
Jeff Johnsone7245742012-09-05 17:12:55 -07006272 ENTER();
6273
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306274 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006275
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306276 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006277 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 "%s: HDD context is not valid", __func__);
6280 *dbm = 0;
6281 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006282 }
6283
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6285 if (NULL == pAdapter)
6286 {
6287 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6288 return -ENOENT;
6289 }
6290
6291 wlan_hdd_get_classAstats(pAdapter);
6292 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6293
Jeff Johnsone7245742012-09-05 17:12:55 -07006294 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 return 0;
6296}
6297
6298static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6299 u8* mac, struct station_info *sinfo)
6300{
6301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6302 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6303 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6304 tANI_U8 rate_flags;
6305
6306 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6307 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006308
6309 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6310 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6311 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6312 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6313 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6314 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6315 tANI_U16 maxRate = 0;
6316 tANI_U16 myRate;
6317 tANI_U16 currentRate = 0;
6318 tANI_U8 maxSpeedMCS = 0;
6319 tANI_U8 maxMCSIdx = 0;
6320 tANI_U8 rateFlag = 1;
6321 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006322 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306323 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006324
Leo Chang6f8870f2013-03-26 18:11:36 -07006325#ifdef WLAN_FEATURE_11AC
6326 tANI_U32 vht_mcs_map;
6327 eDataRate11ACMaxMcs vhtMaxMcs;
6328#endif /* WLAN_FEATURE_11AC */
6329
Jeff Johnsone7245742012-09-05 17:12:55 -07006330 ENTER();
6331
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6333 (0 == ssidlen))
6334 {
6335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6336 " Invalid ssidlen, %d", __func__, ssidlen);
6337 /*To keep GUI happy*/
6338 return 0;
6339 }
6340
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306341 status = wlan_hdd_validate_context(pHddCtx);
6342
6343 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6346 "%s: HDD context is not valid", __func__);
6347 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006348 }
6349
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6351 sinfo->filled |= STATION_INFO_SIGNAL;
6352
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006353 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6355
6356 //convert to the UI units of 100kbps
6357 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6358
6359#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006360 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 -07006361 sinfo->signal,
6362 pCfg->reportMaxLinkSpeed,
6363 myRate,
6364 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006365 (int) pCfg->linkSpeedRssiMid,
6366 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006367 (int) rate_flags,
6368 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006369#endif //LINKSPEED_DEBUG_ENABLED
6370
6371 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6372 {
6373 // we do not want to necessarily report the current speed
6374 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6375 {
6376 // report the max possible speed
6377 rssidx = 0;
6378 }
6379 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6380 {
6381 // report the max possible speed with RSSI scaling
6382 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6383 {
6384 // report the max possible speed
6385 rssidx = 0;
6386 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006387 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 {
6389 // report middle speed
6390 rssidx = 1;
6391 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006392 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6393 {
6394 // report middle speed
6395 rssidx = 2;
6396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 else
6398 {
6399 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006400 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 }
6402 }
6403 else
6404 {
6405 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6406 hddLog(VOS_TRACE_LEVEL_ERROR,
6407 "%s: Invalid value for reportMaxLinkSpeed: %u",
6408 __func__, pCfg->reportMaxLinkSpeed);
6409 rssidx = 0;
6410 }
6411
6412 maxRate = 0;
6413
6414 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306415 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6416 OperationalRates, &ORLeng))
6417 {
6418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6419 /*To keep GUI happy*/
6420 return 0;
6421 }
6422
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 for (i = 0; i < ORLeng; i++)
6424 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006425 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 {
6427 /* Validate Rate Set */
6428 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6429 {
6430 currentRate = supported_data_rate[j].supported_rate[rssidx];
6431 break;
6432 }
6433 }
6434 /* Update MAX rate */
6435 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6436 }
6437
6438 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306439 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6440 ExtendedRates, &ERLeng))
6441 {
6442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6443 /*To keep GUI happy*/
6444 return 0;
6445 }
6446
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 for (i = 0; i < ERLeng; i++)
6448 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006449 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 {
6451 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6452 {
6453 currentRate = supported_data_rate[j].supported_rate[rssidx];
6454 break;
6455 }
6456 }
6457 /* Update MAX rate */
6458 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 /* Get MCS Rate Set -- but only if we are connected at MCS
6461 rates or if we are always reporting max speed or if we have
6462 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006463 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306465 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6466 MCSRates, &MCSLeng))
6467 {
6468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6469 /*To keep GUI happy*/
6470 return 0;
6471 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006473#ifdef WLAN_FEATURE_11AC
6474 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306475 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006477 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306478 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006479 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006481 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006483 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006485 maxMCSIdx = 7;
6486 }
6487 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6488 {
6489 maxMCSIdx = 8;
6490 }
6491 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6492 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306493 //VHT20 is supporting 0~8
6494 if (rate_flags & eHAL_TX_RATE_VHT20)
6495 maxMCSIdx = 8;
6496 else
6497 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006498 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306499
6500 if (rate_flags & eHAL_TX_RATE_VHT80)
6501 {
6502 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6503 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6504 }
6505 else if (rate_flags & eHAL_TX_RATE_VHT40)
6506 {
6507 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6508 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6509 }
6510 else if (rate_flags & eHAL_TX_RATE_VHT20)
6511 {
6512 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6513 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6514 }
6515
Leo Chang6f8870f2013-03-26 18:11:36 -07006516 maxSpeedMCS = 1;
6517 if (currentRate > maxRate)
6518 {
6519 maxRate = currentRate;
6520 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306521
Leo Chang6f8870f2013-03-26 18:11:36 -07006522 }
6523 else
6524#endif /* WLAN_FEATURE_11AC */
6525 {
6526 if (rate_flags & eHAL_TX_RATE_HT40)
6527 {
6528 rateFlag |= 1;
6529 }
6530 if (rate_flags & eHAL_TX_RATE_SGI)
6531 {
6532 rateFlag |= 2;
6533 }
6534
6535 for (i = 0; i < MCSLeng; i++)
6536 {
6537 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6538 for (j = 0; j < temp; j++)
6539 {
6540 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6541 {
6542 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6543 break;
6544 }
6545 }
6546 if ((j < temp) && (currentRate > maxRate))
6547 {
6548 maxRate = currentRate;
6549 maxSpeedMCS = 1;
6550 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6551 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 }
6553 }
6554 }
6555
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306556 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6557 {
6558 maxRate = myRate;
6559 maxSpeedMCS = 1;
6560 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6561 }
6562
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006564 if (((maxRate < myRate) && (0 == rssidx)) ||
6565 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 {
6567 maxRate = myRate;
6568 if (rate_flags & eHAL_TX_RATE_LEGACY)
6569 {
6570 maxSpeedMCS = 0;
6571 }
6572 else
6573 {
6574 maxSpeedMCS = 1;
6575 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6576 }
6577 }
6578
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306579 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 {
6581 sinfo->txrate.legacy = maxRate;
6582#ifdef LINKSPEED_DEBUG_ENABLED
6583 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6584#endif //LINKSPEED_DEBUG_ENABLED
6585 }
6586 else
6587 {
6588 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006589#ifdef WLAN_FEATURE_11AC
6590 sinfo->txrate.nss = 1;
6591 if (rate_flags & eHAL_TX_RATE_VHT80)
6592 {
6593 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306594 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006595 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306596 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006597 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306598 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6599 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6600 }
6601 else if (rate_flags & eHAL_TX_RATE_VHT20)
6602 {
6603 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6604 }
6605#endif /* WLAN_FEATURE_11AC */
6606 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6607 {
6608 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6609 if (rate_flags & eHAL_TX_RATE_HT40)
6610 {
6611 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6612 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006613 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 if (rate_flags & eHAL_TX_RATE_SGI)
6615 {
6616 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6617 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306618
Jeff Johnson295189b2012-06-20 16:38:30 -07006619#ifdef LINKSPEED_DEBUG_ENABLED
6620 pr_info("Reporting MCS rate %d flags %x\n",
6621 sinfo->txrate.mcs,
6622 sinfo->txrate.flags );
6623#endif //LINKSPEED_DEBUG_ENABLED
6624 }
6625 }
6626 else
6627 {
6628 // report current rate instead of max rate
6629
6630 if (rate_flags & eHAL_TX_RATE_LEGACY)
6631 {
6632 //provide to the UI in units of 100kbps
6633 sinfo->txrate.legacy = myRate;
6634#ifdef LINKSPEED_DEBUG_ENABLED
6635 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6636#endif //LINKSPEED_DEBUG_ENABLED
6637 }
6638 else
6639 {
6640 //must be MCS
6641 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006642#ifdef WLAN_FEATURE_11AC
6643 sinfo->txrate.nss = 1;
6644 if (rate_flags & eHAL_TX_RATE_VHT80)
6645 {
6646 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6647 }
6648 else
6649#endif /* WLAN_FEATURE_11AC */
6650 {
6651 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6652 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 if (rate_flags & eHAL_TX_RATE_SGI)
6654 {
6655 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6656 }
6657 if (rate_flags & eHAL_TX_RATE_HT40)
6658 {
6659 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6660 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006661#ifdef WLAN_FEATURE_11AC
6662 else if (rate_flags & eHAL_TX_RATE_VHT80)
6663 {
6664 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6665 }
6666#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006667#ifdef LINKSPEED_DEBUG_ENABLED
6668 pr_info("Reporting actual MCS rate %d flags %x\n",
6669 sinfo->txrate.mcs,
6670 sinfo->txrate.flags );
6671#endif //LINKSPEED_DEBUG_ENABLED
6672 }
6673 }
6674 sinfo->filled |= STATION_INFO_TX_BITRATE;
6675
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006676 sinfo->tx_packets =
6677 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6678 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6679 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6680 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6681
6682 sinfo->tx_retries =
6683 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6684 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6685 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6686 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6687
6688 sinfo->tx_failed =
6689 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6690 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6691 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6692 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6693
6694 sinfo->filled |=
6695 STATION_INFO_TX_PACKETS |
6696 STATION_INFO_TX_RETRIES |
6697 STATION_INFO_TX_FAILED;
6698
6699 EXIT();
6700 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006701}
6702
6703static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6704 struct net_device *dev, bool mode, v_SINT_t timeout)
6705{
6706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306707 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306709 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006710
Jeff Johnsone7245742012-09-05 17:12:55 -07006711 ENTER();
6712
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 if (NULL == pAdapter)
6714 {
6715 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6716 return -ENODEV;
6717 }
6718
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306719 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306720 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306721
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306722 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306723 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6725 "%s: HDD context is not valid", __func__);
6726 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306727 }
6728
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306729 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6730 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6731 (pHddCtx->cfg_ini->fhostArpOffload) &&
6732 (eConnectionState_Associated ==
6733 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6734 {
6735 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6736 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6737 {
6738 hddLog(VOS_TRACE_LEVEL_INFO,
6739 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6740 __func__, vos_status);
6741 }
6742 }
6743
Jeff Johnson295189b2012-06-20 16:38:30 -07006744 /**The get power cmd from the supplicant gets updated by the nl only
6745 *on successful execution of the function call
6746 *we are oppositely mapped w.r.t mode in the driver
6747 **/
6748 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6749
Jeff Johnsone7245742012-09-05 17:12:55 -07006750 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 if (VOS_STATUS_E_FAILURE == vos_status)
6752 {
6753 return -EINVAL;
6754 }
6755 return 0;
6756}
6757
6758
6759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6760static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6761 struct net_device *netdev,
6762 u8 key_index)
6763{
Jeff Johnsone7245742012-09-05 17:12:55 -07006764 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 return 0;
6766}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306767#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006768
6769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6770static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6771 struct net_device *dev,
6772 struct ieee80211_txq_params *params)
6773{
Jeff Johnsone7245742012-09-05 17:12:55 -07006774 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 return 0;
6776}
6777#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6778static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6779 struct ieee80211_txq_params *params)
6780{
Jeff Johnsone7245742012-09-05 17:12:55 -07006781 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 return 0;
6783}
6784#endif //LINUX_VERSION_CODE
6785
6786static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6787 struct net_device *dev, u8 *mac)
6788{
6789 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306790 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006791 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306792 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006793 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006794
Jeff Johnsone7245742012-09-05 17:12:55 -07006795 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306796 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 return -EINVAL;
6800 }
6801
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6803 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006804
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306805 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006806 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6808 "%s: HDD context is not valid", __func__);
6809 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006810 }
6811
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 )
6815 {
6816 if( NULL == mac )
6817 {
6818 v_U16_t i;
6819 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6820 {
6821 if(pAdapter->aStaInfo[i].isUsed)
6822 {
6823 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6824 hddLog(VOS_TRACE_LEVEL_INFO,
6825 "%s: Delete STA with MAC::"
6826 "%02x:%02x:%02x:%02x:%02x:%02x",
6827 __func__,
6828 macAddr[0], macAddr[1], macAddr[2],
6829 macAddr[3], macAddr[4], macAddr[5]);
6830 hdd_softap_sta_deauth(pAdapter, macAddr);
6831 }
6832 }
6833 }
6834 else
6835 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006836
6837 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6838 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6839 {
6840 hddLog(VOS_TRACE_LEVEL_INFO,
6841 "%s: Skip this DEL STA as this is not used::"
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 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6850 {
6851 hddLog(VOS_TRACE_LEVEL_INFO,
6852 "%s: Skip this DEL STA as deauth is in progress::"
6853 "%02x:%02x:%02x:%02x:%02x:%02x",
6854 __func__,
6855 mac[0], mac[1], mac[2],
6856 mac[3], mac[4], mac[5]);
6857 return -ENOENT;
6858 }
6859
6860 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6861
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 hddLog(VOS_TRACE_LEVEL_INFO,
6863 "%s: Delete STA with MAC::"
6864 "%02x:%02x:%02x:%02x:%02x:%02x",
6865 __func__,
6866 mac[0], mac[1], mac[2],
6867 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006868
6869 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6870 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6871 {
6872 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6873 hddLog(VOS_TRACE_LEVEL_INFO,
6874 "%s: STA removal failed for ::"
6875 "%02x:%02x:%02x:%02x:%02x:%02x",
6876 __func__,
6877 mac[0], mac[1], mac[2],
6878 mac[3], mac[4], mac[5]);
6879 return -ENOENT;
6880 }
6881
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 }
6883 }
6884
6885 EXIT();
6886
6887 return 0;
6888}
6889
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006890static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6891 struct net_device *dev, u8 *mac, struct station_parameters *params)
6892{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006893 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006894#ifdef FEATURE_WLAN_TDLS
6895 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006896 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006897 mask = params->sta_flags_mask;
6898
6899 set = params->sta_flags_set;
6900
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006901#ifdef WLAN_FEATURE_TDLS_DEBUG
6902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6903 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6904 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6905#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006906
6907 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6908 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006909 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006910 }
6911 }
6912#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006913 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006914}
6915
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006916
6917#ifdef FEATURE_WLAN_LFR
6918static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006919 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006920{
6921#define MAX_PMKSAIDS_IN_CACHE 8
6922 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306923 static tANI_U32 i; // HDD Local Cache index
6924 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6926 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306927 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306928 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006929 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306930 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931
Jeff Johnsone7245742012-09-05 17:12:55 -07006932 ENTER();
6933
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306934 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306935 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 return -EINVAL;
6939 }
6940
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306941 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6942 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306944 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006945 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6947 "%s: HDD context is not valid", __func__);
6948 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949 }
6950
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306951 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006952 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6953
6954 for (j = 0; j < i; j++)
6955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306956 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957 pmksa->bssid, WNI_CFG_BSSID_LEN))
6958 {
6959 /* BSSID matched previous entry. Overwrite it. */
6960 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306961 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306963 vos_mem_copy(PMKIDCache[j].PMKID,
6964 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006965 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306966 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006967 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006968 dump_bssid(pmksa->bssid);
6969 dump_pmkid(halHandle, pmksa->pmkid);
6970 break;
6971 }
6972 }
6973
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006974 /* Check we compared all entries,if then take the first slot now */
6975 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6976
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006977 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306978 {
6979 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6980 vos_mem_copy(PMKIDCache[i].BSSID,
6981 pmksa->bssid, ETHER_ADDR_LEN);
6982 vos_mem_copy(PMKIDCache[i].PMKID,
6983 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006984 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306985 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006986 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006987 dump_bssid(pmksa->bssid);
6988 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006990 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992 }
6993
6994
6995 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306996 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006997 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306998 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006999 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007000 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307001 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7002 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007003 i );
7004 return 0;
7005}
7006
7007
7008static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007009 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007010{
Jeff Johnsone7245742012-09-05 17:12:55 -07007011 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007012 // TODO: Implement this later.
7013 return 0;
7014}
7015
7016static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7017{
Jeff Johnsone7245742012-09-05 17:12:55 -07007018 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007019 // TODO: Implement this later.
7020 return 0;
7021}
7022#endif
7023
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007024#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307025static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007026 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7027{
7028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7029 hdd_station_ctx_t *pHddStaCtx;
7030
7031 if (NULL == pAdapter)
7032 {
7033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7034 return -ENODEV;
7035 }
7036
7037 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7038
7039 // Added for debug on reception of Re-assoc Req.
7040 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007043 ftie->ie_len);
7044 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7045 }
7046
7047#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307048 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007049 ftie->ie_len);
7050#endif
7051
7052 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307053 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7054 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007055 ftie->ie_len);
7056 return 0;
7057}
7058#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007059
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307060#ifdef FEATURE_WLAN_SCAN_PNO
7061
7062void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7063 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7064{
7065 int ret;
7066 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7067 hdd_context_t *pHddCtx;
7068
7069 if (NULL == pAdapter)
7070 {
7071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7072 "%s: HDD adapter is Null", __func__);
7073 return ;
7074 }
7075
7076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7077 if (NULL == pHddCtx)
7078 {
7079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7080 "%s: HDD context is Null!!!", __func__);
7081 return ;
7082 }
7083
7084 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7085
7086 if (0 > ret)
7087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7088
7089 cfg80211_sched_scan_results(pHddCtx->wiphy);
7090}
7091
7092/*
7093 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7094 * NL interface to enable PNO
7095 */
7096static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7097 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7098{
7099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7100 tpSirPNOScanReq pPnoRequest = NULL;
7101 hdd_context_t *pHddCtx;
7102 tHalHandle hHal;
7103 v_U32_t i, indx, num_ch;
7104 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7105 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7106 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7107 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307108 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307109
7110 if (NULL == pAdapter)
7111 {
7112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7113 "%s: HDD adapter is Null", __func__);
7114 return -ENODEV;
7115 }
7116
7117 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307118 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307119
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307120 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307121 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7123 "%s: HDD context is not valid", __func__);
7124 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307125 }
7126
7127 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7128 if (NULL == hHal)
7129 {
7130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7131 "%s: HAL context is Null!!!", __func__);
7132 return -EAGAIN;
7133 }
7134
7135 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7136 if (NULL == pPnoRequest)
7137 {
7138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7139 "%s: vos_mem_malloc failed", __func__);
7140 return -ENODEV;
7141 }
7142
7143 pPnoRequest->enable = 1; /*Enable PNO */
7144 pPnoRequest->ucNetworksCount = request->n_match_sets;
7145
7146 if (( !pPnoRequest->ucNetworksCount ) ||
7147 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7148 {
7149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7150 "Network input is not correct");
7151 goto error;
7152 }
7153
7154 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7155 {
7156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7157 "Incorrect number of channels");
7158 goto error;
7159 }
7160
7161 /* Framework provides one set of channels(all)
7162 * common for all saved profile */
7163 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7164 channels_allowed, &num_channels_allowed))
7165 {
7166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7167 "%s: failed to get valid channel list", __func__);
7168 goto error;
7169 }
7170 /* Checking each channel against allowed channel list */
7171 num_ch = 0;
7172 for (i = 0; i < request->n_channels; i++)
7173 {
7174 for (indx = 0; indx < num_channels_allowed; indx++)
7175 {
7176 if (request->channels[i]->hw_value == channels_allowed[indx])
7177 {
7178 valid_ch[num_ch++] = request->channels[i]->hw_value;
7179 break ;
7180 }
7181 }
7182 }
7183
7184 /* Filling per profile params */
7185 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7186 {
7187 pPnoRequest->aNetworks[i].ssId.length =
7188 request->match_sets[i].ssid.ssid_len;
7189
7190 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7191 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7192 {
7193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7194 "SSID Len %d is not correct for network %d",
7195 pPnoRequest->aNetworks[i].ssId.length, i);
7196 goto error;
7197 }
7198
7199 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7200 request->match_sets[i].ssid.ssid,
7201 request->match_sets[i].ssid.ssid_len);
7202 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7203 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7204 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7205
7206 /*Copying list of valid channel into request */
7207 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7208 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7209
7210 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7211 }
7212
7213 /* framework provides interval in ms */
7214 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7215 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7216 (request->interval)/1000;
7217 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7218 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7219
7220 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7221 pPnoRequest, pAdapter->sessionId,
7222 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7223 if (eHAL_STATUS_SUCCESS != status)
7224 {
7225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7226 "Failed to enable PNO");
7227 goto error;
7228 }
7229
7230error:
7231 vos_mem_free(pPnoRequest);
7232 return status;
7233}
7234
7235/*
7236 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7237 * NL interface to disable PNO
7238 */
7239static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7240 struct net_device *dev)
7241{
7242 eHalStatus status = eHAL_STATUS_FAILURE;
7243 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7244 hdd_context_t *pHddCtx;
7245 tHalHandle hHal;
7246 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307247 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307248
7249 ENTER();
7250
7251 if (NULL == pAdapter)
7252 {
7253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7254 "%s: HDD adapter is Null", __func__);
7255 return -ENODEV;
7256 }
7257
7258 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307259 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307260
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307261 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307262 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7264 "%s: HDD context is not valid", __func__);
7265 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307266 }
7267
7268 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7269 if (NULL == hHal)
7270 {
7271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7272 "%s: HAL context is Null!!!", __func__);
7273 return -EAGAIN;
7274 }
7275
7276 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7277 if (NULL == pPnoRequest)
7278 {
7279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7280 "%s: vos_mem_malloc failed", __func__);
7281 return -ENODEV;
7282 }
7283
7284 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7285 pPnoRequest->enable = 0; /* Disable PNO */
7286 pPnoRequest->ucNetworksCount = 0;
7287
7288 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7289 pAdapter->sessionId,
7290 NULL, pAdapter);
7291 if (eHAL_STATUS_SUCCESS != status)
7292 {
7293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7294 "Failed to disabled PNO");
7295 }
7296
7297 vos_mem_free(pPnoRequest);
7298
7299 EXIT();
7300 return status;
7301}
7302
7303#endif /*FEATURE_WLAN_SCAN_PNO*/
7304
7305
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007306#ifdef FEATURE_WLAN_TDLS
7307static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7308 u8 *peer, u8 action_code, u8 dialog_token,
7309 u16 status_code, const u8 *buf, size_t len)
7310{
7311
7312 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7313 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007314 u8 peerMac[6];
7315 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007316 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007317 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007318 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007319
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007320 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007321 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007323 "Invalid arguments");
7324 return -EINVAL;
7325 }
7326
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007327 if (pHddCtx->isLogpInProgress)
7328 {
7329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7330 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007331 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007332 return -EBUSY;
7333 }
7334
Hoonki Lee27511902013-03-14 18:19:06 -07007335 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007336 {
Hoonki Lee27511902013-03-14 18:19:06 -07007337 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7338 "%s: TDLS mode is disabled OR not enabled in FW."
7339 MAC_ADDRESS_STR " action %d declined.",
7340 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007341 return -ENOTSUPP;
7342 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007343
Hoonki Lee27511902013-03-14 18:19:06 -07007344 /* other than teardown frame, other mgmt frames are not sent if disabled */
7345 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7346 {
7347 /* if tdls_mode is disabled to respond to peer's request */
7348 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7349 {
7350 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7351 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007352 " TDLS mode is disabled. action %d declined.",
7353 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007354
7355 return -ENOTSUPP;
7356 }
7357 }
7358
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007359 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7360 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007361 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007362 {
7363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007364 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007365 " TDLS setup is ongoing. action %d declined.",
7366 __func__, MAC_ADDR_ARRAY(peer), action_code);
7367 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007368 }
7369 }
7370
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007371 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7372 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007373 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007374 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007375 {
7376 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7377 we return error code at 'add_station()'. Hence we have this
7378 check again in addtion to add_station().
7379 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007380 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007381 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7383 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007384 " TDLS Max peer already connected. action %d declined.",
7385 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007386 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007387 }
7388 else
7389 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007390 /* maximum reached. tweak to send error code to peer and return
7391 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007392 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7394 "%s: " MAC_ADDRESS_STR
7395 " TDLS Max peer already connected send response status %d",
7396 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007397 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007398 /* fall through to send setup resp with failure status
7399 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007400 }
7401 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007402 else
7403 {
7404 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007405 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007406 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007407 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007409 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7410 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007411 return -EPERM;
7412 }
7413 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007414 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007415 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007416
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007417#ifdef WLAN_FEATURE_TDLS_DEBUG
7418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007419 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7420 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7421 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007422#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007423
Hoonki Leea34dd892013-02-05 22:56:02 -08007424 /*Except teardown responder will not be used so just make 0*/
7425 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007426 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007427 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007428
7429 hddTdlsPeer_t *pTdlsPeer;
7430 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7431
7432 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7433 responder = pTdlsPeer->is_responder;
7434 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007435 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7437 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7438 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7439 dialog_token, status_code, len);
7440 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007441 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007442 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007443
Hoonki Lee14621352013-04-16 17:51:19 -07007444 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7445 (SIR_MAC_TDLS_DIS_RSP == action_code))
7446 {
7447 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7448 {
7449 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7450 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7451 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7452 }
7453 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7454 }
7455
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007456 /* make sure doesn't call send_mgmt() while it is pending */
7457 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7458 {
7459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7460 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7461 __func__, MAC_ADDR_ARRAY(peer), action_code);
7462 return -EBUSY;
7463 }
7464
7465 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007466 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7467
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007468 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007469 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007470
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007471 if (VOS_STATUS_SUCCESS != status)
7472 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7474 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007475 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007476 wlan_hdd_tdls_check_bmps(pAdapter);
7477 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007478 }
7479
Hoonki Leed37cbb32013-04-20 00:31:14 -07007480 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7481 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7482
7483 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007484 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7486 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7487 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007488 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007489 wlan_hdd_tdls_check_bmps(pAdapter);
7490 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007491 }
7492
Gopichand Nakkala05922802013-03-14 12:23:19 -07007493 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007494 {
7495 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007496 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007497 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007498
Hoonki Leea34dd892013-02-05 22:56:02 -08007499 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7500 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007501 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007502 }
7503 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7504 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007505 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007506 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007507
7508 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007509error:
7510 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7511 because we already know that this transaction will be failed,
7512 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7513 to be safe, do not change the state mahine.
7514 */
7515 if(max_sta_failed == 0 &&
7516 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7517 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7518 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007519}
7520
7521static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7522 u8 *peer, enum nl80211_tdls_operation oper)
7523{
7524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7525 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307526 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307527#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7528 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307529 tANI_U8 staIdx;
7530#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007531#ifdef WLAN_FEATURE_TDLS_DEBUG
7532 const char *tdls_oper_str[]= {
7533 "NL80211_TDLS_DISCOVERY_REQ",
7534 "NL80211_TDLS_SETUP",
7535 "NL80211_TDLS_TEARDOWN",
7536 "NL80211_TDLS_ENABLE_LINK",
7537 "NL80211_TDLS_DISABLE_LINK",
7538 "NL80211_TDLS_UNKONW_OPER"};
7539#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007540 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007541
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307542 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007543 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007545 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007546 return -EINVAL;
7547 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007548
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307549 status = wlan_hdd_validate_context(pHddCtx);
7550
7551 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007552 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7554 "%s: HDD context is not valid", __func__);
7555 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007556 }
7557
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007558 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7559
7560 if ( NULL == pTdlsPeer ) {
7561 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7562 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7563 return -EINVAL;
7564 }
7565
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007566#ifdef WLAN_FEATURE_TDLS_DEBUG
7567 if((int)oper > 4)
7568 oper = 5;
7569
7570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007571 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7572 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007573 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007574#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007575
7576 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007577 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007578 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007580 "TDLS Disabled in INI OR not enabled in FW. "
7581 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007582 return -ENOTSUPP;
7583 }
7584
7585 switch (oper) {
7586 case NL80211_TDLS_ENABLE_LINK:
7587 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007588 VOS_STATUS status;
7589
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007590 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7591 {
7592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7593 MAC_ADDRESS_STR " failed",
7594 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7595 return -EINVAL;
7596 }
7597
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007598 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007599 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007600 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307601 /* Mark TDLS client Authenticated .*/
7602 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7603 pTdlsPeer->staId,
7604 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007605 if (VOS_STATUS_SUCCESS == status)
7606 {
Hoonki Lee14621352013-04-16 17:51:19 -07007607 if (pTdlsPeer->is_responder == 0)
7608 {
7609 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7610
7611 wlan_hdd_tdls_timer_restart(pAdapter,
7612 &pTdlsPeer->initiatorWaitTimeoutTimer,
7613 WAIT_TIME_TDLS_INITIATOR);
7614 /* suspend initiator TX until it receives direct packet from the
7615 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7616 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7617 &staId, NULL);
7618 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007619 wlan_hdd_tdls_increment_peer_count(pAdapter);
7620 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007621 wlan_hdd_tdls_check_bmps(pAdapter);
7622 }
7623
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007624 }
7625 break;
7626 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007627 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007628 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007629 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007630 long status;
7631
7632 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7633
Lee Hoonkic1262f22013-01-24 21:59:00 -08007634 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7635 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007636
7637 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7638 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7639 if (status <= 0)
7640 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007641 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7643 "%s: Del station failed status %ld",
7644 __func__, status);
7645 return -EPERM;
7646 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007647 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007648 }
7649 else
7650 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7652 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007653 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307654#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7655 if (pHddTdlsCtx->defer_link_lost_indication)
7656 {
7657 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7658 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7659 {
7660 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7661 if ( 0 != status)
7662 {
7663 hddLog(VOS_TRACE_LEVEL_ERROR,
7664 "%s wlan_hdd_disconnect failure, returned %d \n",
7665 __func__, (int)status );
7666 return -EINVAL;
7667 }
7668 }
7669 }
7670#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007671 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007672 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007673 case NL80211_TDLS_TEARDOWN:
7674 case NL80211_TDLS_SETUP:
7675 case NL80211_TDLS_DISCOVERY_REQ:
7676 /* We don't support in-driver setup/teardown/discovery */
7677 return -ENOTSUPP;
7678 default:
7679 return -ENOTSUPP;
7680 }
7681 return 0;
7682}
Chilam NG571c65a2013-01-19 12:27:36 +05307683
7684int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7685 struct net_device *dev, u8 *peer)
7686{
7687 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7688 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7689
7690 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7691 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7692}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007693#endif
7694
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307695#ifdef WLAN_FEATURE_GTK_OFFLOAD
7696/*
7697 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7698 * Callback rountine called upon receiving response for
7699 * get offload info
7700 */
7701void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7702 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7703{
7704
7705 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7706
7707 ENTER();
7708
7709 if (NULL == pAdapter)
7710 {
7711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7712 "%s: HDD adapter is Null", __func__);
7713 return ;
7714 }
7715
7716 if (NULL == pGtkOffloadGetInfoRsp)
7717 {
7718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7719 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7720 return ;
7721 }
7722
7723 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7724 {
7725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7726 "%s: wlan Failed to get replay counter value",
7727 __func__);
7728 return ;
7729 }
7730
7731 /* Update replay counter to NL */
7732 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7733 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7734}
7735
7736/*
7737 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7738 * This function is used to offload GTK rekeying job to the firmware.
7739 */
7740int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7741 struct cfg80211_gtk_rekey_data *data)
7742{
7743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7744 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7745 hdd_station_ctx_t *pHddStaCtx;
7746 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307747 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307748 tpSirGtkOffloadParams pGtkOffloadReqParams;
7749 eHalStatus status = eHAL_STATUS_FAILURE;
7750
7751 ENTER();
7752
7753 if (NULL == pAdapter)
7754 {
7755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7756 "%s: HDD adapter is Null", __func__);
7757 return -ENODEV;
7758 }
7759
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307760 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307761
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307762 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307763 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7765 "%s: HDD context is not valid", __func__);
7766 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307767 }
7768
7769 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7770 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7771 if (NULL == hHal)
7772 {
7773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7774 "%s: HAL context is Null!!!", __func__);
7775 return -EAGAIN;
7776 }
7777
7778 pGtkOffloadReqParams =
7779 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7780
7781 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7782 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7783 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7784 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7785 WNI_CFG_BSSID_LEN);
7786 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7787 sizeof (tANI_U64));
7788
7789 if (TRUE == pHddCtx->hdd_wlan_suspended)
7790 {
7791 /* if wlan is suspended, enable GTK offload directly from here */
7792 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7793 pAdapter->sessionId);
7794
7795 if (eHAL_STATUS_SUCCESS != status)
7796 {
7797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7798 "%s: sme_SetGTKOffload failed, returned %d",
7799 __func__, status);
7800 return status;
7801 }
7802 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7804 "%s: sme_SetGTKOffload successfull", __func__);
7805 }
7806 else
7807 {
7808 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7810 "%s: wlan not suspended GTKOffload request is stored",
7811 __func__);
7812 return eHAL_STATUS_SUCCESS;
7813 }
7814 return status;
7815}
7816#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7817
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307818/*
7819 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7820 * This function is used to set access control policy
7821 */
7822static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7823 struct net_device *dev, const struct cfg80211_acl_data *params)
7824{
7825 int i;
7826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7827 hdd_hostapd_state_t *pHostapdState;
7828 tsap_Config_t *pConfig;
7829 v_CONTEXT_t pVosContext = NULL;
7830 hdd_context_t *pHddCtx;
7831 int status;
7832
7833 ENTER();
7834
7835 if (NULL == pAdapter)
7836 {
7837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7838 "%s: HDD adapter is Null", __func__);
7839 return -ENODEV;
7840 }
7841
7842 if (NULL == params)
7843 {
7844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7845 "%s: params is Null", __func__);
7846 return -EINVAL;
7847 }
7848
7849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7850 status = wlan_hdd_validate_context(pHddCtx);
7851
7852 if (0 != status)
7853 {
7854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7855 "%s: HDD context is not valid", __func__);
7856 return status;
7857 }
7858
7859 pVosContext = pHddCtx->pvosContext;
7860 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7861
7862 if (NULL == pHostapdState)
7863 {
7864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7865 "%s: pHostapdState is Null", __func__);
7866 return -EINVAL;
7867 }
7868
7869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7870 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7871
7872 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7873 {
7874 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7875
7876 /* default value */
7877 pConfig->num_accept_mac = 0;
7878 pConfig->num_deny_mac = 0;
7879
7880 /**
7881 * access control policy
7882 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7883 * listed in hostapd.deny file.
7884 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7885 * listed in hostapd.accept file.
7886 */
7887 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7888 {
7889 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7890 }
7891 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
7892 {
7893 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7894 }
7895 else
7896 {
7897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7898 "%s:Acl Policy : %d is not supported",
7899 __func__, params->acl_policy);
7900 return -ENOTSUPP;
7901 }
7902
7903 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
7904 {
7905 pConfig->num_accept_mac = params->n_acl_entries;
7906 for (i = 0; i < params->n_acl_entries; i++)
7907 {
7908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7909 "** Add ACL MAC entry %i in WhiletList :"
7910 MAC_ADDRESS_STR, i,
7911 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7912
7913 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
7914 sizeof(qcmacaddr));
7915 }
7916 }
7917 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
7918 {
7919 pConfig->num_deny_mac = params->n_acl_entries;
7920 for (i = 0; i < params->n_acl_entries; i++)
7921 {
7922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7923 "** Add ACL MAC entry %i in BlackList :"
7924 MAC_ADDRESS_STR, i,
7925 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7926
7927 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
7928 sizeof(qcmacaddr));
7929 }
7930 }
7931
7932 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
7933 {
7934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7935 "%s: SAP Set Mac Acl fail", __func__);
7936 return -EINVAL;
7937 }
7938 }
7939 else
7940 {
7941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7942 "%s: Invalid device_mode = %d",
7943 __func__, pAdapter->device_mode);
7944 return -EINVAL;
7945 }
7946
7947 return 0;
7948}
7949
Jeff Johnson295189b2012-06-20 16:38:30 -07007950/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307951static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007952{
7953 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7954 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7955 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7956 .change_station = wlan_hdd_change_station,
7957#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7958 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7959 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7960 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007961#else
7962 .start_ap = wlan_hdd_cfg80211_start_ap,
7963 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7964 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007965#endif
7966 .change_bss = wlan_hdd_cfg80211_change_bss,
7967 .add_key = wlan_hdd_cfg80211_add_key,
7968 .get_key = wlan_hdd_cfg80211_get_key,
7969 .del_key = wlan_hdd_cfg80211_del_key,
7970 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007973#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 .scan = wlan_hdd_cfg80211_scan,
7975 .connect = wlan_hdd_cfg80211_connect,
7976 .disconnect = wlan_hdd_cfg80211_disconnect,
7977 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7978 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7979 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7980 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7981 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7983 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7984 .mgmt_tx = wlan_hdd_action,
7985#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7986 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7987 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7988 .set_txq_params = wlan_hdd_set_txq_params,
7989#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 .get_station = wlan_hdd_cfg80211_get_station,
7991 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7992 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007993 .add_station = wlan_hdd_cfg80211_add_station,
7994#ifdef FEATURE_WLAN_LFR
7995 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7996 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7997 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7998#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007999#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8000 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8001#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008002#ifdef FEATURE_WLAN_TDLS
8003 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8004 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8005#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308006#ifdef WLAN_FEATURE_GTK_OFFLOAD
8007 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8008#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308009#ifdef FEATURE_WLAN_SCAN_PNO
8010 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8011 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8012#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308013 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008014};
8015