blob: e33f4db548fb3a0827eeb9b7759b9539ca2db361 [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 */
2682 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 goto done;
2684 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002686 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2688 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002689 goto done;
2690 default:
2691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2692 __func__);
2693 return -EOPNOTSUPP;
2694
2695 }
2696
2697 }
2698 else
2699 {
2700 return -EOPNOTSUPP;
2701 }
2702
2703
2704 if(pRoamProfile)
2705 {
2706 if ( LastBSSType != pRoamProfile->BSSType )
2707 {
2708 /*interface type changed update in wiphy structure*/
2709 wdev->iftype = type;
2710
2711 /*the BSS mode changed, We need to issue disconnect
2712 if connected or in IBSS disconnect state*/
2713 if ( hdd_connGetConnectedBssType(
2714 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2715 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2716 {
2717 /*need to issue a disconnect to CSR.*/
2718 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2719 if( eHAL_STATUS_SUCCESS ==
2720 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2721 pAdapter->sessionId,
2722 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2723 {
2724 wait_for_completion_interruptible_timeout(
2725 &pAdapter->disconnect_comp_var,
2726 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2727 }
2728 }
2729 }
2730 }
2731
2732done:
2733 /*set bitmask based on updated value*/
2734 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2735#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302736 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002737 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2738 {
2739 //we are ok to do AMP
2740 pHddCtx->isAmpAllowed = VOS_TRUE;
2741 }
2742#endif //WLAN_BTAMP_FEATURE
2743 EXIT();
2744 return 0;
2745}
2746
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002747#ifdef FEATURE_WLAN_TDLS
2748static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2749 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2750{
2751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2752 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2753 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002754 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002755
2756 ENTER();
2757
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302758 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002759 {
2760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2761 "Invalid arguments");
2762 return -EINVAL;
2763 }
Hoonki Lee27511902013-03-14 18:19:06 -07002764
2765 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2766 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2767 {
2768 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2769 "%s: TDLS mode is disabled OR not enabled in FW."
2770 MAC_ADDRESS_STR " Request declined.",
2771 __func__, MAC_ADDR_ARRAY(mac));
2772 return -ENOTSUPP;
2773 }
2774
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002775 if (pHddCtx->isLogpInProgress)
2776 {
2777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2778 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002779 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002780 return -EBUSY;
2781 }
2782
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002783 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2784
2785 if ( NULL == pTdlsPeer ) {
2786 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2787 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2788 __func__, MAC_ADDR_ARRAY(mac), update);
2789 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002790 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002791
2792 /* in add station, we accept existing valid staId if there is */
2793 if ((0 == update) &&
2794 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2795 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002796 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002797 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002798 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002799 " link_status %d. staId %d. add station ignored.",
2800 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2801 return 0;
2802 }
2803 /* in change station, we accept only when staId is valid */
2804 if ((1 == update) &&
2805 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2806 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2809 "%s: " MAC_ADDRESS_STR
2810 " link status %d. staId %d. change station %s.",
2811 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2812 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2813 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002814 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002815
2816 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002817 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002818 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: " MAC_ADDRESS_STR
2821 " TDLS setup is ongoing. Request declined.",
2822 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002823 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002824 }
2825
2826 /* first to check if we reached to maximum supported TDLS peer.
2827 TODO: for now, return -EPERM looks working fine,
2828 but need to check if any other errno fit into this category.*/
2829 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2830 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "%s: " MAC_ADDRESS_STR
2833 " TDLS Max peer already connected. Request declined.",
2834 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002835 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002836 }
2837 else
2838 {
2839 hddTdlsPeer_t *pTdlsPeer;
2840 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002841 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002842 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2844 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2845 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002846 return -EPERM;
2847 }
2848 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002849 if (0 == update)
2850 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002851
Jeff Johnsond75fe012013-04-06 10:53:06 -07002852 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302853 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002854 {
2855 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2856 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002857 if(StaParams->htcap_present)
2858 {
2859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2860 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2861 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2862 "ht_capa->extended_capabilities: %0x",
2863 StaParams->HTCap.extendedHtCapInfo);
2864 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "params->capability: %0x",StaParams->capability);
2867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2868 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002869 if(StaParams->vhtcap_present)
2870 {
2871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2872 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2873 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2874 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2875 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002876 {
2877 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002879 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2880 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2881 "[%d]: %x ", i, StaParams->supported_rates[i]);
2882 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002883 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302884 else if ((1 == update) && (NULL == StaParams))
2885 {
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2887 "%s : update is true, but staParams is NULL. Error!", __func__);
2888 return -EPERM;
2889 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002890
2891 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2892
2893 if (!update)
2894 {
2895 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2896 pAdapter->sessionId, mac);
2897 }
2898 else
2899 {
2900 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2901 pAdapter->sessionId, mac, StaParams);
2902 }
2903
2904 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2905 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2906
2907 if (!status)
2908 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002910 "%s: timeout waiting for tdls add station indication",
2911 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002912 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002913 }
2914 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2915 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002917 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002918 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002919 }
2920
2921 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002922
2923error:
2924 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2925 return -EPERM;
2926
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002927}
2928#endif
2929
Jeff Johnson295189b2012-06-20 16:38:30 -07002930static int wlan_hdd_change_station(struct wiphy *wiphy,
2931 struct net_device *dev,
2932 u8 *mac,
2933 struct station_parameters *params)
2934{
2935 VOS_STATUS status = VOS_STATUS_SUCCESS;
2936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302937 hdd_context_t *pHddCtx;
2938 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002940#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002941 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002942 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002943#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002944 ENTER();
2945
Gopichand Nakkala29149562013-05-10 21:43:41 +05302946 if ((NULL == pAdapter))
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2949 "invalid adapter ");
2950 return -EINVAL;
2951 }
2952
2953 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2954 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2955
2956 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2957 {
2958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2959 "invalid HDD state or HDD station context");
2960 return -EINVAL;
2961 }
2962
2963 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002964 {
2965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2966 "%s:LOGP in Progress. Ignore!!!", __func__);
2967 return -EAGAIN;
2968 }
2969
Jeff Johnson295189b2012-06-20 16:38:30 -07002970 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2971
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002972 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2973 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002975 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302977 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002978 WLANTL_STA_AUTHENTICATED);
2979
Gopichand Nakkala29149562013-05-10 21:43:41 +05302980 if (status != VOS_STATUS_SUCCESS)
2981 {
2982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2983 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2984 return -EINVAL;
2985 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002986 }
2987 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002988 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2989 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302990#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002991 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2992 StaParams.capability = params->capability;
2993 StaParams.uapsd_queues = params->uapsd_queues;
2994 StaParams.max_sp = params->max_sp;
2995
2996 if (0 != params->ext_capab_len)
2997 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2998 sizeof(StaParams.extn_capability));
2999
3000 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003001 {
3002 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003003 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003004 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003005
3006 StaParams.supported_rates_len = params->supported_rates_len;
3007
3008 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3009 * The supported_rates array , for all the structures propogating till Add Sta
3010 * to the firmware has to be modified , if the supplicant (ieee80211) is
3011 * modified to send more rates.
3012 */
3013
3014 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3015 */
3016 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3017 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3018
3019 if (0 != StaParams.supported_rates_len) {
3020 int i = 0;
3021 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3022 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003024 "Supported Rates with Length %d", StaParams.supported_rates_len);
3025 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003027 "[%d]: %0x", i, StaParams.supported_rates[i]);
3028 }
3029
3030 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003031 {
3032 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003033 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003034 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003035
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003036 if (0 != params->ext_capab_len ) {
3037 /*Define A Macro : TODO Sunil*/
3038 if ((1<<4) & StaParams.extn_capability[3]) {
3039 isBufSta = 1;
3040 }
3041 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003042 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3043 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003044 //if (VOS_STATUS_SUCCESS != status) {
3045 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3046 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3047 // return -EINVAL;
3048 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003049 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3050
3051 if (VOS_STATUS_SUCCESS != status) {
3052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3053 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3054 return -EINVAL;
3055 }
3056 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003057#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303058 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3059 {
3060 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3061 WLANTL_STA_AUTHENTICATED);
3062 if (status != VOS_STATUS_SUCCESS)
3063 {
3064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3065 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3066 return -EINVAL;
3067 }
3068 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3070 "%s: TL Moving to Authenticated state", __func__);
3071 }
3072 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303073
Jeff Johnsone7245742012-09-05 17:12:55 -07003074 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003075 return status;
3076}
3077
3078/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 * FUNCTION: wlan_hdd_cfg80211_add_key
3080 * This function is used to initialize the key information
3081 */
3082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003083static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 struct net_device *ndev,
3085 u8 key_index, bool pairwise,
3086 const u8 *mac_addr,
3087 struct key_params *params
3088 )
3089#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003090static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003091 struct net_device *ndev,
3092 u8 key_index, const u8 *mac_addr,
3093 struct key_params *params
3094 )
3095#endif
3096{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003097 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 tCsrRoamSetKey setKey;
3099 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303100 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003101 v_U32_t roamId= 0xFF;
3102 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 hdd_hostapd_state_t *pHostapdState;
3104 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003105 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303106 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003107
3108 ENTER();
3109
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3111 status = wlan_hdd_validate_context(pHddCtx);
3112
3113 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003114 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "%s: HDD context is not valid", __func__);
3117 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003118 }
3119
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3121 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003122
3123 if (CSR_MAX_NUM_KEY <= key_index)
3124 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003126 key_index);
3127
3128 return -EINVAL;
3129 }
3130
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003131 if (CSR_MAX_KEY_LEN < params->key_len)
3132 {
3133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3134 params->key_len);
3135
3136 return -EINVAL;
3137 }
3138
3139 hddLog(VOS_TRACE_LEVEL_INFO,
3140 "%s: called with key index = %d & key length %d",
3141 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003142
3143 /*extract key idx, key len and key*/
3144 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3145 setKey.keyId = key_index;
3146 setKey.keyLength = params->key_len;
3147 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3148
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003149 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 {
3151 case WLAN_CIPHER_SUITE_WEP40:
3152 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3153 break;
3154
3155 case WLAN_CIPHER_SUITE_WEP104:
3156 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3157 break;
3158
3159 case WLAN_CIPHER_SUITE_TKIP:
3160 {
3161 u8 *pKey = &setKey.Key[0];
3162 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3163
3164 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3165
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003167
3168 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003169 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003170 |--------------|----------|----------|
3171 <---16bytes---><--8bytes--><--8bytes-->
3172
3173 */
3174 /*Sme expects the 32 bytes key to be in the below order
3175
3176 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003177 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003178 |--------------|----------|----------|
3179 <---16bytes---><--8bytes--><--8bytes-->
3180 */
3181 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003185 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003188 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003189
3190
3191 break;
3192 }
3193
3194 case WLAN_CIPHER_SUITE_CCMP:
3195 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3196 break;
3197
3198#ifdef FEATURE_WLAN_WAPI
3199 case WLAN_CIPHER_SUITE_SMS4:
3200 {
3201 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3202 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3203 params->key, params->key_len);
3204 return 0;
3205 }
3206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003207
Jeff Johnson295189b2012-06-20 16:38:30 -07003208#ifdef FEATURE_WLAN_CCX
3209 case WLAN_CIPHER_SUITE_KRK:
3210 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3211 break;
3212#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003213
3214#ifdef WLAN_FEATURE_11W
3215 case WLAN_CIPHER_SUITE_AES_CMAC:
3216 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003217 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003218#endif
3219
Jeff Johnson295189b2012-06-20 16:38:30 -07003220 default:
3221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3222 __func__, params->cipher);
3223 return -EOPNOTSUPP;
3224 }
3225
3226 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3227 __func__, setKey.encType);
3228
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003229 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3231 (!pairwise)
3232#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003233 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003234#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003235 )
3236 {
3237 /* set group key*/
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3239 "%s- %d: setting Broadcast key",
3240 __func__, __LINE__);
3241 setKey.keyDirection = eSIR_RX_ONLY;
3242 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3243 }
3244 else
3245 {
3246 /* set pairwise key*/
3247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s- %d: setting pairwise key",
3249 __func__, __LINE__);
3250 setKey.keyDirection = eSIR_TX_RX;
3251 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3252 }
3253 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3254 {
3255 setKey.keyDirection = eSIR_TX_RX;
3256 /*Set the group key*/
3257 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3258 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003259
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003260 if ( 0 != status )
3261 {
3262 hddLog(VOS_TRACE_LEVEL_ERROR,
3263 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3264 return -EINVAL;
3265 }
3266 /*Save the keys here and call sme_RoamSetKey for setting
3267 the PTK after peer joins the IBSS network*/
3268 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3269 &setKey, sizeof(tCsrRoamSetKey));
3270 return status;
3271 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303272 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3273 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3274 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003276 if( pHostapdState->bssState == BSS_START )
3277 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003278 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3279
3280 if ( status != eHAL_STATUS_SUCCESS )
3281 {
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3283 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3284 __LINE__, status );
3285 }
3286 }
3287
3288 /* Saving WEP keys */
3289 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3290 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3291 {
3292 //Save the wep key in ap context. Issue setkey after the BSS is started.
3293 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3294 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3295 }
3296 else
3297 {
3298 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003299 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003300 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3301 }
3302 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003303 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3304 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003305 {
3306 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3307 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3308
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303309#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3310 if (!pairwise)
3311#else
3312 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3313#endif
3314 {
3315 /* set group key*/
3316 if (pHddStaCtx->roam_info.deferKeyComplete)
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3319 "%s- %d: Perform Set key Complete",
3320 __func__, __LINE__);
3321 hdd_PerformRoamSetKeyComplete(pAdapter);
3322 }
3323 }
3324
Jeff Johnson295189b2012-06-20 16:38:30 -07003325 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3326
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003327 pWextState->roamProfile.Keys.defaultIndex = key_index;
3328
3329
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003330 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 params->key, params->key_len);
3332
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303333
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3335
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303336 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003337 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303338 __func__, setKey.peerMac[0], setKey.peerMac[1],
3339 setKey.peerMac[2], setKey.peerMac[3],
3340 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003341 setKey.keyDirection);
3342
3343 vos_status = wlan_hdd_check_ula_done(pAdapter);
3344
3345 if ( vos_status != VOS_STATUS_SUCCESS )
3346 {
3347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3348 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3349 __LINE__, vos_status );
3350
3351 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3352
3353 return -EINVAL;
3354
3355 }
3356
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003357#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303358 /* The supplicant may attempt to set the PTK once pre-authentication
3359 is done. Save the key in the UMAC and include it in the ADD BSS
3360 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003361 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303362 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003363 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303364 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3365 "%s: Update PreAuth Key success", __func__);
3366 return 0;
3367 }
3368 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3369 {
3370 hddLog(VOS_TRACE_LEVEL_ERROR,
3371 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303372 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003373 }
3374#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003375
3376 /* issue set key request to SME*/
3377 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3378 pAdapter->sessionId, &setKey, &roamId );
3379
3380 if ( 0 != status )
3381 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303382 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003383 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3384 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3385 return -EINVAL;
3386 }
3387
3388
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 /* in case of IBSS as there was no information available about WEP keys during
3390 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003391 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303392 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3393 !( ( IW_AUTH_KEY_MGMT_802_1X
3394 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3396 )
3397 &&
3398 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3399 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3400 )
3401 )
3402 {
3403 setKey.keyDirection = eSIR_RX_ONLY;
3404 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3405
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303406 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003407 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303408 __func__, setKey.peerMac[0], setKey.peerMac[1],
3409 setKey.peerMac[2], setKey.peerMac[3],
3410 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 setKey.keyDirection);
3412
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303413 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003414 pAdapter->sessionId, &setKey, &roamId );
3415
3416 if ( 0 != status )
3417 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303418 hddLog(VOS_TRACE_LEVEL_ERROR,
3419 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003420 __func__, status);
3421 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3422 return -EINVAL;
3423 }
3424 }
3425 }
3426
3427 return 0;
3428}
3429
3430/*
3431 * FUNCTION: wlan_hdd_cfg80211_get_key
3432 * This function is used to get the key information
3433 */
3434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303435static int wlan_hdd_cfg80211_get_key(
3436 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003437 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303438 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003439 const u8 *mac_addr, void *cookie,
3440 void (*callback)(void *cookie, struct key_params*)
3441 )
3442#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303443static int wlan_hdd_cfg80211_get_key(
3444 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003445 struct net_device *ndev,
3446 u8 key_index, const u8 *mac_addr, void *cookie,
3447 void (*callback)(void *cookie, struct key_params*)
3448 )
3449#endif
3450{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303451 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003452 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3453 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3454 struct key_params params;
3455
3456 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3459 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303460
Jeff Johnson295189b2012-06-20 16:38:30 -07003461 memset(&params, 0, sizeof(params));
3462
3463 if (CSR_MAX_NUM_KEY <= key_index)
3464 {
3465 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003467
3468 switch(pRoamProfile->EncryptionType.encryptionType[0])
3469 {
3470 case eCSR_ENCRYPT_TYPE_NONE:
3471 params.cipher = IW_AUTH_CIPHER_NONE;
3472 break;
3473
3474 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3475 case eCSR_ENCRYPT_TYPE_WEP40:
3476 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3477 break;
3478
3479 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3480 case eCSR_ENCRYPT_TYPE_WEP104:
3481 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3482 break;
3483
3484 case eCSR_ENCRYPT_TYPE_TKIP:
3485 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3486 break;
3487
3488 case eCSR_ENCRYPT_TYPE_AES:
3489 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3490 break;
3491
3492 default:
3493 params.cipher = IW_AUTH_CIPHER_NONE;
3494 break;
3495 }
3496
3497 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3498 params.seq_len = 0;
3499 params.seq = NULL;
3500 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3501 callback(cookie, &params);
3502 return 0;
3503}
3504
3505/*
3506 * FUNCTION: wlan_hdd_cfg80211_del_key
3507 * This function is used to delete the key information
3508 */
3509#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303510static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303512 u8 key_index,
3513 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003514 const u8 *mac_addr
3515 )
3516#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303517static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003518 struct net_device *ndev,
3519 u8 key_index,
3520 const u8 *mac_addr
3521 )
3522#endif
3523{
3524 int status = 0;
3525
3526 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303527 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003528 //it is observed that this is invalidating peer
3529 //key index whenever re-key is done. This is affecting data link.
3530 //It should be ok to ignore del_key.
3531#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3533 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003534 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3535 tCsrRoamSetKey setKey;
3536 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303537
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 ENTER();
3539
3540 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3541 __func__,pAdapter->device_mode);
3542
3543 if (CSR_MAX_NUM_KEY <= key_index)
3544 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 key_index);
3547
3548 return -EINVAL;
3549 }
3550
3551 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3552 setKey.keyId = key_index;
3553
3554 if (mac_addr)
3555 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3556 else
3557 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3558
3559 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3560
3561 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003562 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303563 )
3564 {
3565
3566 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003567 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3568 if( pHostapdState->bssState == BSS_START)
3569 {
3570 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303571
Jeff Johnson295189b2012-06-20 16:38:30 -07003572 if ( status != eHAL_STATUS_SUCCESS )
3573 {
3574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3575 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3576 __LINE__, status );
3577 }
3578 }
3579 }
3580 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303581 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003582 )
3583 {
3584 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3585
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303586 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3587
3588 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303590 __func__, setKey.peerMac[0], setKey.peerMac[1],
3591 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303593 if(pAdapter->sessionCtx.station.conn_info.connState ==
3594 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003595 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303596 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 if ( 0 != status )
3600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303601 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 "%s: sme_RoamSetKey failure, returned %d",
3603 __func__, status);
3604 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3605 return -EINVAL;
3606 }
3607 }
3608 }
3609#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003610 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 return status;
3612}
3613
3614/*
3615 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3616 * This function is used to set the default tx key index
3617 */
3618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3619static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3620 struct net_device *ndev,
3621 u8 key_index,
3622 bool unicast, bool multicast)
3623#else
3624static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3625 struct net_device *ndev,
3626 u8 key_index)
3627#endif
3628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303630 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303631 hdd_wext_state_t *pWextState;
3632 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303633 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003634
3635 ENTER();
3636
Gopichand Nakkala29149562013-05-10 21:43:41 +05303637 if ((NULL == pAdapter))
3638 {
3639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3640 "invalid adapter");
3641 return -EINVAL;
3642 }
3643
3644 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3645 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3646
3647 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3648 {
3649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3650 "invalid Wext state or HDD context");
3651 return -EINVAL;
3652 }
3653
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3655 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303656
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 if (CSR_MAX_NUM_KEY <= key_index)
3658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 key_index);
3661
3662 return -EINVAL;
3663 }
3664
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303665 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3666 status = wlan_hdd_validate_context(pHddCtx);
3667
3668 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003669 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3671 "%s: HDD context is not valid", __func__);
3672 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003673 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303674
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003676 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303677 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003678 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303679 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303681 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 pWextState->roamProfile.EncryptionType.encryptionType[0])
3683 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303684 {
3685 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003686 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303687
Jeff Johnson295189b2012-06-20 16:38:30 -07003688 tCsrRoamSetKey setKey;
3689 v_U32_t roamId= 0xFF;
3690 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691
3692 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003693 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303694
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 Keys->defaultIndex = (u8)key_index;
3696 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3697 setKey.keyId = key_index;
3698 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303699
3700 vos_mem_copy(&setKey.Key[0],
3701 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003702 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703
Gopichand Nakkala29149562013-05-10 21:43:41 +05303704 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303705
3706 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 &pHddStaCtx->conn_info.bssId[0],
3708 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303709
Gopichand Nakkala29149562013-05-10 21:43:41 +05303710 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3711 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3712 eCSR_ENCRYPT_TYPE_WEP104)
3713 {
3714 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3715 even though ap is configured for WEP-40 encryption. In this canse the key length
3716 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3717 type(104) and switching encryption type to 40*/
3718 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3719 eCSR_ENCRYPT_TYPE_WEP40;
3720 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3721 eCSR_ENCRYPT_TYPE_WEP40;
3722 }
3723
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303724 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003725 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303726
Jeff Johnson295189b2012-06-20 16:38:30 -07003727 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303728 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003729 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303730
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 if ( 0 != status )
3732 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303733 hddLog(VOS_TRACE_LEVEL_ERROR,
3734 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 status);
3736 return -EINVAL;
3737 }
3738 }
3739 }
3740
3741 /* In SoftAp mode setting key direction for default mode */
3742 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3743 {
3744 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3745 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3746 (eCSR_ENCRYPT_TYPE_AES !=
3747 pWextState->roamProfile.EncryptionType.encryptionType[0])
3748 )
3749 {
3750 /* Saving key direction for default key index to TX default */
3751 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3752 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3753 }
3754 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303755
Jeff Johnson295189b2012-06-20 16:38:30 -07003756 return status;
3757}
3758
Jeff Johnson295189b2012-06-20 16:38:30 -07003759/*
3760 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3761 * This function is used to inform the BSS details to nl80211 interface.
3762 */
3763static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3764 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3765{
3766 struct net_device *dev = pAdapter->dev;
3767 struct wireless_dev *wdev = dev->ieee80211_ptr;
3768 struct wiphy *wiphy = wdev->wiphy;
3769 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3770 int chan_no;
3771 int ie_length;
3772 const char *ie;
3773 unsigned int freq;
3774 struct ieee80211_channel *chan;
3775 int rssi = 0;
3776 struct cfg80211_bss *bss = NULL;
3777
3778 ENTER();
3779
3780 if( NULL == pBssDesc )
3781 {
3782 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3783 return bss;
3784 }
3785
3786 chan_no = pBssDesc->channelId;
3787 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3788 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3789
3790 if( NULL == ie )
3791 {
3792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3793 return bss;
3794 }
3795
3796#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3797 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3798 {
3799 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3800 }
3801 else
3802 {
3803 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3804 }
3805#else
3806 freq = ieee80211_channel_to_frequency(chan_no);
3807#endif
3808
3809 chan = __ieee80211_get_channel(wiphy, freq);
3810
3811 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3812 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3813 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3814 if (bss == NULL)
3815 {
3816 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3817
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303818 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3819 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003820 pBssDesc->capabilityInfo,
3821 pBssDesc->beaconInterval, ie, ie_length,
3822 rssi, GFP_KERNEL ));
3823}
3824 else
3825 {
3826 return bss;
3827 }
3828}
3829
3830
3831
3832/*
3833 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3834 * This function is used to inform the BSS details to nl80211 interface.
3835 */
3836struct cfg80211_bss*
3837wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3838 tSirBssDescription *bss_desc
3839 )
3840{
3841 /*
3842 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3843 already exists in bss data base of cfg80211 for that particular BSS ID.
3844 Using cfg80211_inform_bss_frame to update the bss entry instead of
3845 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3846 now there is no possibility to get the mgmt(probe response) frame from PE,
3847 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3848 cfg80211_inform_bss_frame.
3849 */
3850 struct net_device *dev = pAdapter->dev;
3851 struct wireless_dev *wdev = dev->ieee80211_ptr;
3852 struct wiphy *wiphy = wdev->wiphy;
3853 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003854#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3855 qcom_ie_age *qie_age = NULL;
3856 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3857#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003859#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003860 const char *ie =
3861 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3862 unsigned int freq;
3863 struct ieee80211_channel *chan;
3864 struct ieee80211_mgmt *mgmt =
3865 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3866 struct cfg80211_bss *bss_status = NULL;
3867 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3868 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003869#ifdef WLAN_OPEN_SOURCE
3870 struct timespec ts;
3871#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003872
3873 ENTER();
3874
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003875 if (!mgmt)
3876 return NULL;
3877
Jeff Johnson295189b2012-06-20 16:38:30 -07003878 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003879
3880#ifdef WLAN_OPEN_SOURCE
3881 /* Android does not want the timestamp from the frame.
3882 Instead it wants a monotonic increasing value */
3883 get_monotonic_boottime(&ts);
3884 mgmt->u.probe_resp.timestamp =
3885 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3886#else
3887 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3889 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003890
3891#endif
3892
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3894 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003895
3896#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3897 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3898 /* Assuming this is the last IE, copy at the end */
3899 ie_length -=sizeof(qcom_ie_age);
3900 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3901 qie_age->element_id = QCOM_VENDOR_IE_ID;
3902 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3903 qie_age->oui_1 = QCOM_OUI1;
3904 qie_age->oui_2 = QCOM_OUI2;
3905 qie_age->oui_3 = QCOM_OUI3;
3906 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3907 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3908#endif
3909
Jeff Johnson295189b2012-06-20 16:38:30 -07003910 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303911 if (bss_desc->fProbeRsp)
3912 {
3913 mgmt->frame_control |=
3914 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3915 }
3916 else
3917 {
3918 mgmt->frame_control |=
3919 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003921
3922#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303923 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003924 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3925 {
3926 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3927 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303928 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3930
3931 {
3932 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3933 }
3934 else
3935 {
3936 kfree(mgmt);
3937 return NULL;
3938 }
3939#else
3940 freq = ieee80211_channel_to_frequency(chan_no);
3941#endif
3942 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003943 /*when the band is changed on the fly using the GUI, three things are done
3944 * 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)
3945 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3946 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3947 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3948 * and discards the channels correponding to previous band and calls back with zero bss results.
3949 * 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
3950 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3951 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3952 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3953 * So drop the bss and continue to next bss.
3954 */
3955 if(chan == NULL)
3956 {
3957 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003958 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003959 return NULL;
3960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303962 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 * */
3964 if (( eConnectionState_Associated ==
3965 pAdapter->sessionCtx.station.conn_info.connState ) &&
3966 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3967 pAdapter->sessionCtx.station.conn_info.bssId,
3968 WNI_CFG_BSSID_LEN)))
3969 {
3970 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3971 rssi = (pAdapter->rssi * 100);
3972 }
3973 else
3974 {
3975 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3976 }
3977
3978 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3979 frame_len, rssi, GFP_KERNEL);
3980 kfree(mgmt);
3981 return bss_status;
3982}
3983
3984/*
3985 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3986 * This function is used to update the BSS data base of CFG8011
3987 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303988struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003989 tCsrRoamInfo *pRoamInfo
3990 )
3991{
3992 tCsrRoamConnectedProfile roamProfile;
3993 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3994 struct cfg80211_bss *bss = NULL;
3995
3996 ENTER();
3997
3998 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3999 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4000
4001 if (NULL != roamProfile.pBssDesc)
4002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304003 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 &roamProfile);
4005
4006 if (NULL == bss)
4007 {
4008 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4009 __func__);
4010 }
4011
4012 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4013 }
4014 else
4015 {
4016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4017 __func__);
4018 }
4019 return bss;
4020}
4021
4022/*
4023 * FUNCTION: wlan_hdd_cfg80211_update_bss
4024 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304025static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4026 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004027 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304028{
Jeff Johnson295189b2012-06-20 16:38:30 -07004029 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4030 tCsrScanResultInfo *pScanResult;
4031 eHalStatus status = 0;
4032 tScanResultHandle pResult;
4033 struct cfg80211_bss *bss_status = NULL;
4034
4035 ENTER();
4036
4037 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4038 {
4039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4040 return -EAGAIN;
4041 }
4042
4043 /*
4044 * start getting scan results and populate cgf80211 BSS database
4045 */
4046 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4047
4048 /* no scan results */
4049 if (NULL == pResult)
4050 {
4051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4052 return status;
4053 }
4054
4055 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4056
4057 while (pScanResult)
4058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304059 /*
4060 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4061 * entry already exists in bss data base of cfg80211 for that
4062 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4063 * bss entry instead of cfg80211_inform_bss, But this call expects
4064 * mgmt packet as input. As of now there is no possibility to get
4065 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 * ieee80211_mgmt(probe response) and passing to c
4067 * fg80211_inform_bss_frame.
4068 * */
4069
4070 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4071 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304072
Jeff Johnson295189b2012-06-20 16:38:30 -07004073
4074 if (NULL == bss_status)
4075 {
4076 hddLog(VOS_TRACE_LEVEL_INFO,
4077 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4078 }
4079 else
4080 {
4081 cfg80211_put_bss(bss_status);
4082 }
4083
4084 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4085 }
4086
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304087 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004088
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304089 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004090}
4091
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004092void
4093hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4094{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304095 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004096 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4097 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4098 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004099} /****** end hddPrintMacAddr() ******/
4100
4101void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004102hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004103{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304104 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004105 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4106 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4107 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4108 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004109} /****** end hddPrintPmkId() ******/
4110
4111//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4112//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4113
4114//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4115//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4116
4117#define dump_bssid(bssid) \
4118 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004119 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4120 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4121 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004122 }
4123
4124#define dump_pmkid(pMac, pmkid) \
4125 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004126 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4127 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4128 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004129 }
4130
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004131#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004132/*
4133 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4134 * This function is used to notify the supplicant of a new PMKSA candidate.
4135 */
4136int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304137 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138 int index, bool preauth )
4139{
Jeff Johnsone7245742012-09-05 17:12:55 -07004140#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004141 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004142 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143
4144 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004145 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004146
4147 if( NULL == pRoamInfo )
4148 {
4149 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4150 return -EINVAL;
4151 }
4152
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004153 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4154 {
4155 dump_bssid(pRoamInfo->bssid);
4156 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004157 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004158 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004159#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304160 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004161}
4162#endif //FEATURE_WLAN_LFR
4163
Jeff Johnson295189b2012-06-20 16:38:30 -07004164/*
4165 * FUNCTION: hdd_cfg80211_scan_done_callback
4166 * scanning callback function, called after finishing scan
4167 *
4168 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004170 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4171{
4172 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304173 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004175 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4176 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 struct cfg80211_scan_request *req = NULL;
4178 int ret = 0;
4179
4180 ENTER();
4181
4182 hddLog(VOS_TRACE_LEVEL_INFO,
4183 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 __func__, halHandle, pContext, (int) scanId, (int) status);
4186
4187 //Block on scan req completion variable. Can't wait forever though.
4188 ret = wait_for_completion_interruptible_timeout(
4189 &pScanInfo->scan_req_completion_event,
4190 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4191 if (!ret)
4192 {
4193 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004194 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004195 }
4196
4197 if(pScanInfo->mScanPending != VOS_TRUE)
4198 {
4199 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004200 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 }
4202
4203 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304204 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 {
4206 hddLog(VOS_TRACE_LEVEL_INFO,
4207 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 (int) scanId);
4210 }
4211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304212 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 pAdapter);
4214
4215 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004217
4218
4219 /* If any client wait scan result through WEXT
4220 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004221 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 {
4223 /* The other scan request waiting for current scan finish
4224 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004225 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004226 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004227 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 }
4229 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004230 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 {
4232 struct net_device *dev = pAdapter->dev;
4233 union iwreq_data wrqu;
4234 int we_event;
4235 char *msg;
4236
4237 memset(&wrqu, '\0', sizeof(wrqu));
4238 we_event = SIOCGIWSCAN;
4239 msg = NULL;
4240 wireless_send_event(dev, we_event, &wrqu, msg);
4241 }
4242 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004243 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
4245 /* Get the Scan Req */
4246 req = pAdapter->request;
4247
4248 if (!req)
4249 {
4250 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004251 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004252 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004253 }
4254
4255 /*
4256 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304257 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 req->n_ssids = 0;
4259 req->n_channels = 0;
4260 req->ie = 0;
4261
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004263 /* Scan is no longer pending */
4264 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004265
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004266 /*
4267 * cfg80211_scan_done informing NL80211 about completion
4268 * of scanning
4269 */
4270 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004271 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004272
Jeff Johnsone7245742012-09-05 17:12:55 -07004273allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004274 /* release the wake lock at the end of the scan*/
4275 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004276
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004277 /* Acquire wakelock to handle the case where APP's tries to suspend
4278 * immediatly after the driver gets connect request(i.e after scan)
4279 * from supplicant, this result in app's is suspending and not able
4280 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004281 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004282
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004283#ifdef FEATURE_WLAN_TDLS
4284 wlan_hdd_tdls_scan_done_callback(pAdapter);
4285#endif
4286
Jeff Johnson295189b2012-06-20 16:38:30 -07004287 EXIT();
4288 return 0;
4289}
4290
4291/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004292 * FUNCTION: hdd_isScanAllowed
4293 * Go through each adapter and check if scan allowed
4294 *
4295 */
4296v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4297{
4298 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4299 hdd_station_ctx_t *pHddStaCtx = NULL;
4300 hdd_adapter_t *pAdapter = NULL;
4301 VOS_STATUS status = 0;
4302 v_U8_t staId = 0;
4303 v_U8_t *staMac = NULL;
4304
4305 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4306
4307 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4308 {
4309 pAdapter = pAdapterNode->pAdapter;
4310
4311 if( pAdapter )
4312 {
4313 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304314 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004315 __func__, pAdapter->device_mode);
4316 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4317 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4318 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4319 {
4320 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4321 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4322 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4323 {
4324 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304327 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004328 staMac[0], staMac[1], staMac[2],
4329 staMac[3], staMac[4], staMac[5]);
4330 return VOS_FALSE;
4331 }
4332 }
4333 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4334 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4335 {
4336 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304338 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004339 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4340 {
4341 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4342
4343 hddLog(VOS_TRACE_LEVEL_ERROR,
4344 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304345 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004346 staMac[0], staMac[1], staMac[2],
4347 staMac[3], staMac[4], staMac[5]);
4348 return VOS_FALSE;
4349 }
4350 }
4351 }
4352 }
4353 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4354 pAdapterNode = pNext;
4355 }
4356 hddLog(VOS_TRACE_LEVEL_INFO,
4357 "%s: Scan allowed", __func__);
4358 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304359}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004360
4361/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004362 * FUNCTION: wlan_hdd_cfg80211_scan
4363 * this scan respond to scan trigger and update cfg80211 scan database
4364 * later, scan dump command can be used to recieve scan results
4365 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004366int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4367#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4368 struct net_device *dev,
4369#endif
4370 struct cfg80211_scan_request *request)
4371{
4372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4373 struct net_device *dev = request->wdev->netdev;
4374#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304375 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4377 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304378 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 tCsrScanRequest scanRequest;
4380 tANI_U8 *channelList = NULL, i;
4381 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304382 int status;
4383 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004385
4386 ENTER();
4387
4388 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4389 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004390
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304391 status = wlan_hdd_validate_context(pHddCtx);
4392
4393 if (0 != status)
4394 {
4395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4396 "%s: HDD context is not valid", __func__);
4397 return status;
4398 }
4399
4400 cfg_param = pHddCtx->cfg_ini;
4401 pScanInfo = &pHddCtx->scan_info;
4402
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004403 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004404 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004405 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004406 {
4407 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004408 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4409 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004410 return -EBUSY;
4411 }
4412
Jeff Johnson295189b2012-06-20 16:38:30 -07004413#ifdef WLAN_BTAMP_FEATURE
4414 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004415 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004416 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004418 "%s: No scanning when AMP is on", __func__);
4419 return -EOPNOTSUPP;
4420 }
4421#endif
4422 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004423 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004424 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004425 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004426 "%s: Not scanning on device_mode = %d",
4427 __func__, pAdapter->device_mode);
4428 return -EOPNOTSUPP;
4429 }
4430
4431 if (TRUE == pScanInfo->mScanPending)
4432 {
4433 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004434 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004435 }
4436
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304437 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004438 //Channel and action frame is pending
4439 //Otherwise Cancel Remain On Channel and allow Scan
4440 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004441 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004442 {
4443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4444 return -EBUSY;
4445 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004446#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004447 /* if tdls disagree scan right now, return immediately.
4448 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4449 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4450 */
4451 status = wlan_hdd_tdls_scan_callback (pAdapter,
4452 wiphy,
4453#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4454 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004455#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004456 request);
4457 if(status <= 0)
4458 {
4459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4460 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004461 }
4462#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004463
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4465 {
4466 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004467 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004470 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4471 {
4472 hddLog(VOS_TRACE_LEVEL_WARN,
4473 "%s: MAX TM Level Scan not allowed", __func__);
4474 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304475 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004476 }
4477 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4478
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004479 /* Check if scan is allowed at this point of time.
4480 */
4481 if (!hdd_isScanAllowed(pHddCtx))
4482 {
4483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4484 return -EBUSY;
4485 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304486
Jeff Johnson295189b2012-06-20 16:38:30 -07004487 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4488
4489 if (NULL != request)
4490 {
4491 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304492 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004493
4494 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4495 * Becasue of this, driver is assuming that this is not wildcard scan and so
4496 * is not aging out the scan results.
4497 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004498 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004499 {
4500 request->n_ssids = 0;
4501 }
4502
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004503 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 {
4505 tCsrSSIDInfo *SsidInfo;
4506 int j;
4507 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4508 /* Allocate num_ssid tCsrSSIDInfo structure */
4509 SsidInfo = scanRequest.SSIDs.SSIDList =
4510 ( tCsrSSIDInfo *)vos_mem_malloc(
4511 request->n_ssids*sizeof(tCsrSSIDInfo));
4512
4513 if(NULL == scanRequest.SSIDs.SSIDList)
4514 {
4515 hddLog(VOS_TRACE_LEVEL_ERROR,
4516 "memory alloc failed SSIDInfo buffer");
4517 return -ENOMEM;
4518 }
4519
4520 /* copy all the ssid's and their length */
4521 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4522 {
4523 /* get the ssid length */
4524 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4525 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4526 SsidInfo->SSID.length);
4527 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4528 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4529 j, SsidInfo->SSID.ssId);
4530 }
4531 /* set the scan type to active */
4532 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4533 }
4534 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4535 {
4536 /* set the scan type to active */
4537 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4538 }
4539 else
4540 {
4541 /*Set the scan type to default type, in this case it is ACTIVE*/
4542 scanRequest.scanType = pScanInfo->scan_mode;
4543 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304544 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004545 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4546 }
4547 else
4548 {
4549 /* set the scan type to active */
4550 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4551 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4552
4553 /* set min and max channel time to zero */
4554 scanRequest.minChnTime = 0;
4555 scanRequest.maxChnTime = 0;
4556 }
4557
4558 /* set BSSType to default type */
4559 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4560
4561 /*TODO: scan the requested channels only*/
4562
4563 /*Right now scanning all the channels */
4564 if( request )
4565 {
4566 if( request->n_channels )
4567 {
4568 channelList = vos_mem_malloc( request->n_channels );
4569 if( NULL == channelList )
4570 {
4571 status = -ENOMEM;
4572 goto free_mem;
4573 }
4574
4575 for( i = 0 ; i < request->n_channels ; i++ )
4576 channelList[i] = request->channels[i]->hw_value;
4577 }
4578
4579 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4580 scanRequest.ChannelInfo.ChannelList = channelList;
4581
4582 /* set requestType to full scan */
4583 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584
4585 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004586 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304587 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004588 */
4589
4590 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304591 * and in that case driver shoudnt flush scan results. If
4592 * driver flushes the scan results here and unfortunately if
4593 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004594 * fails which is not desired
4595 */
4596
4597 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4598 {
4599 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4600 pAdapter->sessionId );
4601 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004602
4603 if( request->ie_len )
4604 {
4605 /* save this for future association (join requires this) */
4606 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4607 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4608 pScanInfo->scanAddIE.length = request->ie_len;
4609
4610 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004611 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4612 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 )
4614 {
4615 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4616 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4617 }
4618
4619 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4620 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4621
Jeff Johnson295189b2012-06-20 16:38:30 -07004622 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4623 request->ie_len);
4624 if (pP2pIe != NULL)
4625 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004626#ifdef WLAN_FEATURE_P2P_DEBUG
4627 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4628 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4629 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4630 {
4631 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4632 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4633 "Go nego completed to Connection is started");
4634 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4635 "for 8way Handshake");
4636 }
4637 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4638 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4639 {
4640 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4641 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4642 "Disconnected state to Connection is started");
4643 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4644 "for 4way Handshake");
4645 }
4646#endif
4647
Jeff Johnsone7245742012-09-05 17:12:55 -07004648 /* no_cck will be set during p2p find to disable 11b rates */
4649 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004651 hddLog(VOS_TRACE_LEVEL_INFO,
4652 "%s: This is a P2P Search", __func__);
4653 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004654
Jeff Johnsone7245742012-09-05 17:12:55 -07004655 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4656 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004657 /* set requestType to P2P Discovery */
4658 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004659 }
4660
4661 /*
4662 Skip Dfs Channel in case of P2P Search
4663 if it is set in ini file
4664 */
4665 if(cfg_param->skipDfsChnlInP2pSearch)
4666 {
4667 scanRequest.skipDfsChnlInP2pSearch = 1;
4668 }
4669 else
4670 {
4671 scanRequest.skipDfsChnlInP2pSearch = 0;
4672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004673
Jeff Johnson295189b2012-06-20 16:38:30 -07004674 }
4675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004676 }
4677 }
4678
4679 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4680
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004681 /* acquire the wakelock to avoid the apps suspend during the scan. To
4682 * address the following issues.
4683 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4684 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4685 * for long time, this result in apps running at full power for long time.
4686 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4687 * be stuck in full power because of resume BMPS
4688 */
4689 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004690
4691 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 pAdapter->sessionId, &scanRequest, &scanId,
4693 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004694
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 if (eHAL_STATUS_SUCCESS != status)
4696 {
4697 hddLog(VOS_TRACE_LEVEL_ERROR,
4698 "%s: sme_ScanRequest returned error %d", __func__, status);
4699 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004700 if(eHAL_STATUS_RESOURCES == status)
4701 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004702 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 -07004703 status = -EBUSY;
4704 } else {
4705 status = -EIO;
4706 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004707 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004708 goto free_mem;
4709 }
4710
4711 pScanInfo->mScanPending = TRUE;
4712 pAdapter->request = request;
4713 pScanInfo->scanId = scanId;
4714
4715 complete(&pScanInfo->scan_req_completion_event);
4716
4717free_mem:
4718 if( scanRequest.SSIDs.SSIDList )
4719 {
4720 vos_mem_free(scanRequest.SSIDs.SSIDList);
4721 }
4722
4723 if( channelList )
4724 vos_mem_free( channelList );
4725
4726 EXIT();
4727
4728 return status;
4729}
4730
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004731
4732void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4733{
4734 v_U8_t iniDot11Mode =
4735 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4736 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4737
4738 switch ( iniDot11Mode )
4739 {
4740 case eHDD_DOT11_MODE_AUTO:
4741 case eHDD_DOT11_MODE_11ac:
4742 case eHDD_DOT11_MODE_11ac_ONLY:
4743#ifdef WLAN_FEATURE_11AC
4744 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4745#else
4746 hddDot11Mode = eHDD_DOT11_MODE_11n;
4747#endif
4748 break;
4749 case eHDD_DOT11_MODE_11n:
4750 case eHDD_DOT11_MODE_11n_ONLY:
4751 hddDot11Mode = eHDD_DOT11_MODE_11n;
4752 break;
4753 default:
4754 hddDot11Mode = iniDot11Mode;
4755 break;
4756 }
4757 /* This call decides required channel bonding mode */
4758 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4759 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4760 operationChannel);
4761}
4762
Jeff Johnson295189b2012-06-20 16:38:30 -07004763/*
4764 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304765 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004766 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304767int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004768 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004769{
4770 int status = 0;
4771 hdd_wext_state_t *pWextState;
4772 v_U32_t roamId;
4773 tCsrRoamProfile *pRoamProfile;
4774 eMib_dot11DesiredBssType connectedBssType;
4775 eCsrAuthType RSNAuthType;
4776
4777 ENTER();
4778
4779 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304780
Jeff Johnson295189b2012-06-20 16:38:30 -07004781 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4782 {
4783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4784 return -EINVAL;
4785 }
4786
4787 pRoamProfile = &pWextState->roamProfile;
4788
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304789 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004790 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004791 int ret = 0;
4792 hdd_station_ctx_t *pHddStaCtx;
4793 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4794 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4795
4796 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4797 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4798 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 {
4800 /* Issue disconnect to CSR */
4801 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304802 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004803 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4804 pAdapter->sessionId,
4805 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4806 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004807 ret = wait_for_completion_interruptible_timeout(
4808 &pAdapter->disconnect_comp_var,
4809 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4810 if (0 == ret)
4811 {
4812 VOS_ASSERT(0);
4813 }
4814 }
4815 }
4816 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4817 {
4818 ret = wait_for_completion_interruptible_timeout(
4819 &pAdapter->disconnect_comp_var,
4820 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4821 if (0 == ret)
4822 {
4823 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 }
4825 }
4826
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304827 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004828 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4829 {
4830 /*QoS not enabled in cfg file*/
4831 pRoamProfile->uapsd_mask = 0;
4832 }
4833 else
4834 {
4835 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304836 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004837 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4838 }
4839
4840 pRoamProfile->SSIDs.numOfSSIDs = 1;
4841 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4842 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304843 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004844 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4845 ssid, ssid_len);
4846
4847 if (bssid)
4848 {
4849 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4850 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4851 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304852 /* Save BSSID in seperate variable as well, as RoamProfile
4853 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004854 case of join failure we should send valid BSSID to supplicant
4855 */
4856 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4857 WNI_CFG_BSSID_LEN);
4858 }
4859
4860 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4861 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304862 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 /*set gen ie*/
4864 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4865 /*set auth*/
4866 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004868#ifdef FEATURE_WLAN_WAPI
4869 if (pAdapter->wapi_info.nWapiMode)
4870 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004871 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 switch (pAdapter->wapi_info.wapiAuthMode)
4873 {
4874 case WAPI_AUTH_MODE_PSK:
4875 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004876 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004877 pAdapter->wapi_info.wapiAuthMode);
4878 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4879 break;
4880 }
4881 case WAPI_AUTH_MODE_CERT:
4882 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004883 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004884 pAdapter->wapi_info.wapiAuthMode);
4885 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4886 break;
4887 }
4888 } // End of switch
4889 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4890 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4891 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004892 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 pRoamProfile->AuthType.numEntries = 1;
4894 pRoamProfile->EncryptionType.numEntries = 1;
4895 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4896 pRoamProfile->mcEncryptionType.numEntries = 1;
4897 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4898 }
4899 }
4900#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304901#ifdef WLAN_FEATURE_GTK_OFFLOAD
4902 /* Initializing gtkOffloadRequestParams */
4903 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4904 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4905 {
4906 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4907 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4908 0, sizeof (tSirGtkOffloadParams));
4909 }
4910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004911 pRoamProfile->csrPersona = pAdapter->device_mode;
4912
Jeff Johnson32d95a32012-09-10 13:15:23 -07004913 if( operatingChannel )
4914 {
4915 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4916 pRoamProfile->ChannelInfo.numOfChannels = 1;
4917 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004918 else
4919 {
4920 pRoamProfile->ChannelInfo.ChannelList = NULL;
4921 pRoamProfile->ChannelInfo.numOfChannels = 0;
4922 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004923 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4924 {
4925 hdd_select_cbmode(pAdapter,operatingChannel);
4926 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004927 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4928 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304929 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004930 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004931 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4932 */
4933 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4934 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4935 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304936
4937 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 pAdapter->sessionId, pRoamProfile, &roamId);
4939
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004940 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304941 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4942
4943 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4945 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4946 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304947 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004948 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304949 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004950
4951 pRoamProfile->ChannelInfo.ChannelList = NULL;
4952 pRoamProfile->ChannelInfo.numOfChannels = 0;
4953
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 }
4955 else
4956 {
4957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4958 return -EINVAL;
4959 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004960 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 return status;
4962}
4963
4964/*
4965 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4966 * This function is used to set the authentication type (OPEN/SHARED).
4967 *
4968 */
4969static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4970 enum nl80211_auth_type auth_type)
4971{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304972 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4974
4975 ENTER();
4976
4977 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304978 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304981 hddLog(VOS_TRACE_LEVEL_INFO,
4982 "%s: set authentication type to AUTOSWITCH", __func__);
4983 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4984 break;
4985
4986 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004987#ifdef WLAN_FEATURE_VOWIFI_11R
4988 case NL80211_AUTHTYPE_FT:
4989#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304990 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 "%s: set authentication type to OPEN", __func__);
4992 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4993 break;
4994
4995 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304996 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 "%s: set authentication type to SHARED", __func__);
4998 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4999 break;
5000#ifdef FEATURE_WLAN_CCX
5001 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305002 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005003 "%s: set authentication type to CCKM WPA", __func__);
5004 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5005 break;
5006#endif
5007
5008
5009 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305010 hddLog(VOS_TRACE_LEVEL_ERROR,
5011 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 auth_type);
5013 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5014 return -EINVAL;
5015 }
5016
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305017 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 pHddStaCtx->conn_info.authType;
5019 return 0;
5020}
5021
5022/*
5023 * FUNCTION: wlan_hdd_set_akm_suite
5024 * This function is used to set the key mgmt type(PSK/8021x).
5025 *
5026 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305027static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 u32 key_mgmt
5029 )
5030{
5031 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5032 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305033
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 /*set key mgmt type*/
5035 switch(key_mgmt)
5036 {
5037 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305038#ifdef WLAN_FEATURE_VOWIFI_11R
5039 case WLAN_AKM_SUITE_FT_PSK:
5040#endif
5041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005042 __func__);
5043 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5044 break;
5045
5046 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305047#ifdef WLAN_FEATURE_VOWIFI_11R
5048 case WLAN_AKM_SUITE_FT_8021X:
5049#endif
5050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 __func__);
5052 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5053 break;
5054#ifdef FEATURE_WLAN_CCX
5055#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5056#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5057 case WLAN_AKM_SUITE_CCKM:
5058 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5059 __func__);
5060 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5061 break;
5062#endif
5063
5064 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 __func__, key_mgmt);
5067 return -EINVAL;
5068
5069 }
5070 return 0;
5071}
5072
5073/*
5074 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 * (NONE/WEP40/WEP104/TKIP/CCMP).
5077 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5079 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 bool ucast
5081 )
5082{
5083 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305084 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5086
5087 ENTER();
5088
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305089 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 __func__, cipher);
5093 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5094 }
5095 else
5096 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305097
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305099 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 {
5101 case IW_AUTH_CIPHER_NONE:
5102 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5103 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305104
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305106 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005107 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305108
Jeff Johnson295189b2012-06-20 16:38:30 -07005109 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305110 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
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_TKIP:
5114 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5115 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305116
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 case WLAN_CIPHER_SUITE_CCMP:
5118 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5119 break;
5120#ifdef FEATURE_WLAN_WAPI
5121 case WLAN_CIPHER_SUITE_SMS4:
5122 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5123 break;
5124#endif
5125
5126#ifdef FEATURE_WLAN_CCX
5127 case WLAN_CIPHER_SUITE_KRK:
5128 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5129 break;
5130#endif
5131 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005133 __func__, cipher);
5134 return -EOPNOTSUPP;
5135 }
5136 }
5137
5138 if (ucast)
5139 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005141 __func__, encryptionType);
5142 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5143 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305144 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 encryptionType;
5146 }
5147 else
5148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 __func__, encryptionType);
5151 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5152 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5153 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5154 }
5155
5156 return 0;
5157}
5158
5159
5160/*
5161 * FUNCTION: wlan_hdd_cfg80211_set_ie
5162 * This function is used to parse WPA/RSN IE's.
5163 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305164int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5165 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 size_t ie_len
5167 )
5168{
5169 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5170 u8 *genie = ie;
5171 v_U16_t remLen = ie_len;
5172#ifdef FEATURE_WLAN_WAPI
5173 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5174 u16 *tmp;
5175 v_U16_t akmsuiteCount;
5176 int *akmlist;
5177#endif
5178 ENTER();
5179
5180 /* clear previous assocAddIE */
5181 pWextState->assocAddIE.length = 0;
5182 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5183
5184 while (remLen >= 2)
5185 {
5186 v_U16_t eLen = 0;
5187 v_U8_t elementId;
5188 elementId = *genie++;
5189 eLen = *genie++;
5190 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305191
5192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194
5195 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005198 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 -07005199 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 "%s: Invalid WPA IE", __func__);
5202 return -EINVAL;
5203 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 {
5206 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305207 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305209
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5211 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005212 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5213 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 VOS_ASSERT(0);
5215 return -ENOMEM;
5216 }
5217 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5218 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5219 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305220
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5222 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5223 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5224 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305225 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5226 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005227 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5228 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5229 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5230 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5231 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305233 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5234 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 /*Consider P2P IE, only for P2P Client */
5236 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5237 {
5238 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305239 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305241
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5243 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005244 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5245 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005246 VOS_ASSERT(0);
5247 return -ENOMEM;
5248 }
5249 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5250 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5251 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305252
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5254 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5255 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005256#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305257 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5258 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 /*Consider WFD IE, only for P2P Client */
5260 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5261 {
5262 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305263 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305265
Jeff Johnson295189b2012-06-20 16:38:30 -07005266 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5267 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005268 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5269 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 VOS_ASSERT(0);
5271 return -ENOMEM;
5272 }
5273 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5274 // WPS IE + P2P IE + WFD IE
5275 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5276 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305277
Jeff Johnson295189b2012-06-20 16:38:30 -07005278 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5279 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5280 }
5281#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005282 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305283 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005284 HS20_OUI_TYPE_SIZE)) )
5285 {
5286 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305287 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005288 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005289
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005290 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5291 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005292 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5293 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005294 VOS_ASSERT(0);
5295 return -ENOMEM;
5296 }
5297 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5298 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005299
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005300 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5301 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5302 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005303
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 break;
5305 case DOT11F_EID_RSN:
5306 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5307 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5308 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5309 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5310 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5311 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005312 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5313 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305314 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005315 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305316 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005317 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305318
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005319 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5320 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005321 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5322 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005323 VOS_ASSERT(0);
5324 return -ENOMEM;
5325 }
5326 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5327 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305328
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005329 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5330 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5331 break;
5332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005333#ifdef FEATURE_WLAN_WAPI
5334 case WLAN_EID_WAPI:
5335 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5336 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5337 pAdapter->wapi_info.nWapiMode);
5338 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305339 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 akmsuiteCount = WPA_GET_LE16(tmp);
5341 tmp = tmp + 1;
5342 akmlist = (int *)(tmp);
5343 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5344 {
5345 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5346 }
5347 else
5348 {
5349 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5350 VOS_ASSERT(0);
5351 return -EINVAL;
5352 }
5353
5354 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5355 {
5356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005357 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005358 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005360 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305361 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005363 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5365 }
5366 break;
5367#endif
5368 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305369 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005370 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005371 /* when Unknown IE is received we should break and continue
5372 * to the next IE in the buffer instead we were returning
5373 * so changing this to break */
5374 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 }
5376 genie += eLen;
5377 remLen -= eLen;
5378 }
5379 EXIT();
5380 return 0;
5381}
5382
5383/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305384 * FUNCTION: hdd_isWPAIEPresent
5385 * Parse the received IE to find the WPA IE
5386 *
5387 */
5388static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5389{
5390 v_U8_t eLen = 0;
5391 v_U16_t remLen = ie_len;
5392 v_U8_t elementId = 0;
5393
5394 while (remLen >= 2)
5395 {
5396 elementId = *ie++;
5397 eLen = *ie++;
5398 remLen -= 2;
5399 if (eLen > remLen)
5400 {
5401 hddLog(VOS_TRACE_LEVEL_ERROR,
5402 "%s: IE length is wrong %d", __func__, eLen);
5403 return FALSE;
5404 }
5405 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5406 {
5407 /* OUI - 0x00 0X50 0XF2
5408 WPA Information Element - 0x01
5409 WPA version - 0x01*/
5410 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5411 return TRUE;
5412 }
5413 ie += eLen;
5414 remLen -= eLen;
5415 }
5416 return FALSE;
5417}
5418
5419/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305421 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 * parameters during connect operation.
5423 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305424int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 struct cfg80211_connect_params *req
5426 )
5427{
5428 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305429 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 ENTER();
5431
5432 /*set wpa version*/
5433 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5434
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 {
5437 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305438 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305439 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305441 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 * since p2p ie is also put in same buffer.
5443 * */
5444 {
5445 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5446 }
5447 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5448 {
5449 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5450 }
5451 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305452
5453 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 pWextState->wpaVersion);
5455
5456 /*set authentication type*/
5457 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5458
5459 if (0 > status)
5460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305461 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 "%s: failed to set authentication type ", __func__);
5463 return status;
5464 }
5465
5466 /*set key mgmt type*/
5467 if (req->crypto.n_akm_suites)
5468 {
5469 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5470 if (0 > status)
5471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 __func__);
5474 return status;
5475 }
5476 }
5477
5478 /*set pairwise cipher type*/
5479 if (req->crypto.n_ciphers_pairwise)
5480 {
5481 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5482 req->crypto.ciphers_pairwise[0], true);
5483 if (0 > status)
5484 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305485 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 "%s: failed to set unicast cipher type", __func__);
5487 return status;
5488 }
5489 }
5490 else
5491 {
5492 /*Reset previous cipher suite to none*/
5493 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5494 if (0 > status)
5495 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305496 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 "%s: failed to set unicast cipher type", __func__);
5498 return status;
5499 }
5500 }
5501
5502 /*set group cipher type*/
5503 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5504 false);
5505
5506 if (0 > status)
5507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 __func__);
5510 return status;
5511 }
5512
Chet Lanctot186b5732013-03-18 10:26:30 -07005513#ifdef WLAN_FEATURE_11W
5514 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5515#endif
5516
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5518 if (req->ie_len)
5519 {
5520 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5521 if ( 0 > status)
5522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 __func__);
5525 return status;
5526 }
5527 }
5528
5529 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305530 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 {
5532 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5533 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5534 )
5535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305536 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5538 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305539 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 __func__);
5541 return -EOPNOTSUPP;
5542 }
5543 else
5544 {
5545 u8 key_len = req->key_len;
5546 u8 key_idx = req->key_idx;
5547
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 && (CSR_MAX_NUM_KEY > key_idx)
5550 )
5551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305552 hddLog(VOS_TRACE_LEVEL_INFO,
5553 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 __func__, key_idx, key_len);
5555 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305556 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305558 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005559 (u8)key_len;
5560 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5561 }
5562 }
5563 }
5564 }
5565
5566 return status;
5567}
5568
5569/*
5570 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 * parameters during connect operation.
5573 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305574static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 struct net_device *ndev,
5576 struct cfg80211_connect_params *req
5577 )
5578{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305579 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5582 hdd_context_t *pHddCtx = NULL;
5583
5584 ENTER();
5585
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305586 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5588
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305589 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5590 status = wlan_hdd_validate_context(pHddCtx);
5591
5592 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5595 "%s: HDD context is not valid", __func__);
5596 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 }
5598
5599#ifdef WLAN_BTAMP_FEATURE
5600 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305601 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305603 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005605 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 }
5607#endif
5608 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305609 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005610
5611 if ( 0 > status)
5612 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 __func__);
5615 return status;
5616 }
5617
5618 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005619 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5621 (vos_concurrent_sessions_running()))
5622 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305623 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 }
5625
Mohit Khanna765234a2012-09-11 15:08:35 -07005626 if ( req->channel )
5627 {
5628 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5629 req->ssid_len, req->bssid,
5630 req->channel->hw_value);
5631 }
5632 else
5633 {
5634 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305635 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005637
5638 if (0 > status)
5639 {
5640 //ReEnable BMPS if disabled
5641 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5642 (NULL != pHddCtx))
5643 {
5644 //ReEnable Bmps and Imps back
5645 hdd_enable_bmps_imps(pHddCtx);
5646 }
5647
5648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5649 return status;
5650 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305651 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 EXIT();
5653 return status;
5654}
5655
5656
5657/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305658 * FUNCTION: wlan_hdd_disconnect
5659 * This function is used to issue a disconnect request to SME
5660 */
5661int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5662{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305663 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305664 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5666
5667 status = wlan_hdd_validate_context(pHddCtx);
5668
5669 if (0 != status)
5670 {
5671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5672 "%s: HDD context is not valid", __func__);
5673 return status;
5674 }
5675
5676 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305677 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305678 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305679
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305680 /*issue disconnect*/
5681 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5682 pAdapter->sessionId, reason);
5683
5684 if ( 0 != status )
5685 {
5686 hddLog(VOS_TRACE_LEVEL_ERROR,
5687 "%s csrRoamDisconnect failure, returned %d \n",
5688 __func__, (int)status );
5689 return -EINVAL;
5690 }
5691 wait_for_completion_interruptible_timeout(
5692 &pAdapter->disconnect_comp_var,
5693 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5694 /*stop tx queues*/
5695 netif_tx_disable(pAdapter->dev);
5696 netif_carrier_off(pAdapter->dev);
5697 return status;
5698}
5699
5700
5701/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 * FUNCTION: wlan_hdd_cfg80211_disconnect
5703 * This function is used to issue a disconnect request to SME
5704 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305705static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 struct net_device *dev,
5707 u16 reason
5708 )
5709{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5711 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305713 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005715 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305716#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005717 tANI_U8 staIdx;
5718#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305719
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305721
5722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 __func__,pAdapter->device_mode);
5724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5726 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005727
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305728 status = wlan_hdd_validate_context(pHddCtx);
5729
5730 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5733 "%s: HDD context is not valid", __func__);
5734 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305736
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 if (NULL != pRoamProfile)
5738 {
5739 /*issue disconnect request to SME, if station is in connected state*/
5740 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5741 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305742 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305744 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 switch(reason)
5746 {
5747 case WLAN_REASON_MIC_FAILURE:
5748 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5749 break;
5750
5751 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5752 case WLAN_REASON_DISASSOC_AP_BUSY:
5753 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5754 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5755 break;
5756
5757 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5758 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5759 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5760 break;
5761
5762 case WLAN_REASON_DEAUTH_LEAVING:
5763 default:
5764 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5765 break;
5766 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305767 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5768 pScanInfo = &pHddCtx->scan_info;
5769 if (pScanInfo->mScanPending)
5770 {
5771 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5772 "Aborting Scan");
5773 hdd_abort_mac_scan(pHddCtx);
5774 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005775
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005776#ifdef FEATURE_WLAN_TDLS
5777 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005778 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005779 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005780 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5781 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005782 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005783 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005784 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005785 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005786 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005787 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005788 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005789 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005790 pAdapter->sessionId,
5791 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005792 }
5793 }
5794#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305795 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5796 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 {
5798 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305799 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 __func__, (int)status );
5801 return -EINVAL;
5802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 }
5804 }
5805 else
5806 {
5807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5808 }
5809
5810 return status;
5811}
5812
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305813
Jeff Johnson295189b2012-06-20 16:38:30 -07005814/*
5815 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305816 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 * settings in IBSS mode.
5818 */
5819static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305820 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 struct cfg80211_ibss_params *params
5822 )
5823{
5824 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5827 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 ENTER();
5830
5831 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5832
5833 if (params->ie_len && ( NULL != params->ie) )
5834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305835 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 {
5837 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5838 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5839 }
5840 else
5841 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005842 tDot11fIEWPA dot11WPAIE;
5843 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5844
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005846 // Unpack the WPA IE
5847 //Skip past the EID byte and length byte - and four byte WiFi OUI
5848 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5849 &params->ie[2+4],
5850 params->ie[1] - 4,
5851 &dot11WPAIE);
5852 /*Extract the multicast cipher, the encType for unicast
5853 cipher for wpa-none is none*/
5854 encryptionType =
5855 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 }
5857 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5858
5859 if (0 > status)
5860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 __func__);
5863 return status;
5864 }
5865 }
5866
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867 pWextState->roamProfile.AuthType.authType[0] =
5868 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005869 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5870
5871 if (params->privacy)
5872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873 /* Security enabled IBSS, At this time there is no information available
5874 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305876 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305878 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 *enable privacy bit in beacons */
5880
5881 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5882 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005883 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5884 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5886 pWextState->roamProfile.EncryptionType.numEntries = 1;
5887 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 return status;
5889}
5890
5891/*
5892 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305893 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 struct net_device *dev,
5897 struct cfg80211_ibss_params *params
5898 )
5899{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5902 tCsrRoamProfile *pRoamProfile;
5903 int status;
5904 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305905 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005906
5907 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305908
5909 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5911
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305912 status = wlan_hdd_validate_context(pHddCtx);
5913
5914 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5917 "%s: HDD context is not valid", __func__);
5918 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 }
5920
5921 if (NULL == pWextState)
5922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305923 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 __func__);
5925 return -EIO;
5926 }
5927
5928 pRoamProfile = &pWextState->roamProfile;
5929
5930 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5931 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 "%s Interface type is not set to IBSS \n", __func__);
5934 return -EINVAL;
5935 }
5936
5937 /* Set Channel */
5938 if (NULL != params->channel)
5939 {
5940 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005941 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5942 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5943 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5944 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005945
5946 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305947 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 ieee80211_frequency_to_channel(params->channel->center_freq);
5949
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005950
5951 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5952 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5955 __func__);
5956 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005958
5959 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005961 if (channelNum == validChan[indx])
5962 {
5963 break;
5964 }
5965 }
5966 if (indx >= numChans)
5967 {
5968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 __func__, channelNum);
5970 return -EINVAL;
5971 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005972 /* Set the Operational Channel */
5973 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5974 channelNum);
5975 pRoamProfile->ChannelInfo.numOfChannels = 1;
5976 pHddStaCtx->conn_info.operationChannel = channelNum;
5977 pRoamProfile->ChannelInfo.ChannelList =
5978 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 }
5980
5981 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305982 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005983 if (status < 0)
5984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 __func__);
5987 return status;
5988 }
5989
5990 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305991 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005992 params->ssid_len, params->bssid,
5993 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005994
5995 if (0 > status)
5996 {
5997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5998 return status;
5999 }
6000
6001 return 0;
6002}
6003
6004/*
6005 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306008static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 struct net_device *dev
6010 )
6011{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306012 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6014 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306015 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6016 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006017
6018 ENTER();
6019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306020 status = wlan_hdd_validate_context(pHddCtx);
6021
6022 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006023 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6025 "%s: HDD context is not valid", __func__);
6026 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006027 }
6028
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6030 if (NULL == pWextState)
6031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306032 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 __func__);
6034 return -EIO;
6035 }
6036
6037 pRoamProfile = &pWextState->roamProfile;
6038
6039 /* Issue disconnect only if interface type is set to IBSS */
6040 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306042 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 __func__);
6044 return -EINVAL;
6045 }
6046
6047 /* Issue Disconnect request */
6048 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6049 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6050 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6051
6052 return 0;
6053}
6054
6055/*
6056 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6057 * This function is used to set the phy parameters
6058 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6059 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306060static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 u32 changed)
6062{
6063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6064 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306065 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006066
6067 ENTER();
6068
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306069 status = wlan_hdd_validate_context(pHddCtx);
6070
6071 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006072 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6074 "%s: HDD context is not valid", __func__);
6075 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006076 }
6077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6079 {
6080 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6081 WNI_CFG_RTS_THRESHOLD_STAMAX :
6082 wiphy->rts_threshold;
6083
6084 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306085 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 hddLog(VOS_TRACE_LEVEL_ERROR,
6088 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 __func__, rts_threshold);
6090 return -EINVAL;
6091 }
6092
6093 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6094 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306097 hddLog(VOS_TRACE_LEVEL_ERROR,
6098 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 __func__, rts_threshold);
6100 return -EIO;
6101 }
6102
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 rts_threshold);
6105 }
6106
6107 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6108 {
6109 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6110 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6111 wiphy->frag_threshold;
6112
6113 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306114 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306116 hddLog(VOS_TRACE_LEVEL_ERROR,
6117 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006118 frag_threshold);
6119 return -EINVAL;
6120 }
6121
6122 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6123 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126 hddLog(VOS_TRACE_LEVEL_ERROR,
6127 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006128 __func__, frag_threshold);
6129 return -EIO;
6130 }
6131
6132 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6133 frag_threshold);
6134 }
6135
6136 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6137 || (changed & WIPHY_PARAM_RETRY_LONG))
6138 {
6139 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6140 wiphy->retry_short :
6141 wiphy->retry_long;
6142
6143 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6144 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 __func__, retry_value);
6148 return -EINVAL;
6149 }
6150
6151 if (changed & WIPHY_PARAM_RETRY_SHORT)
6152 {
6153 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6154 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306155 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306157 hddLog(VOS_TRACE_LEVEL_ERROR,
6158 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 __func__, retry_value);
6160 return -EIO;
6161 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306162 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 __func__, retry_value);
6164 }
6165 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6166 {
6167 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6168 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306169 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171 hddLog(VOS_TRACE_LEVEL_ERROR,
6172 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 __func__, retry_value);
6174 return -EIO;
6175 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306176 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 __func__, retry_value);
6178 }
6179 }
6180
6181 return 0;
6182}
6183
6184/*
6185 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6186 * This function is used to set the txpower
6187 */
6188static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6189#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306190 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006191#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306192 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006193#endif
6194 int dbm)
6195{
6196 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306197 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6199 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306200 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006201
6202 ENTER();
6203
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306204 status = wlan_hdd_validate_context(pHddCtx);
6205
6206 if (0 != status)
6207 {
6208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6209 "%s: HDD context is not valid", __func__);
6210 return status;
6211 }
6212
6213 hHal = pHddCtx->hHal;
6214
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306215 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6216 dbm, ccmCfgSetCallback,
6217 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306219 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6221 return -EIO;
6222 }
6223
6224 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6225 dbm);
6226
6227 switch(type)
6228 {
6229 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6230 /* Fall through */
6231 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6232 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6235 __func__);
6236 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 }
6238 break;
6239 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 __func__);
6242 return -EOPNOTSUPP;
6243 break;
6244 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6246 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 return -EIO;
6248 }
6249
6250 return 0;
6251}
6252
6253/*
6254 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6255 * This function is used to read the txpower
6256 */
6257static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6258{
6259
6260 hdd_adapter_t *pAdapter;
6261 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306262 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006263
Jeff Johnsone7245742012-09-05 17:12:55 -07006264 ENTER();
6265
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306266 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006267
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306268 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006269 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6271 "%s: HDD context is not valid", __func__);
6272 *dbm = 0;
6273 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006274 }
6275
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6277 if (NULL == pAdapter)
6278 {
6279 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6280 return -ENOENT;
6281 }
6282
6283 wlan_hdd_get_classAstats(pAdapter);
6284 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6285
Jeff Johnsone7245742012-09-05 17:12:55 -07006286 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 return 0;
6288}
6289
6290static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6291 u8* mac, struct station_info *sinfo)
6292{
6293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6294 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6295 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6296 tANI_U8 rate_flags;
6297
6298 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6299 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006300
6301 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6302 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6303 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6304 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6305 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6306 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6307 tANI_U16 maxRate = 0;
6308 tANI_U16 myRate;
6309 tANI_U16 currentRate = 0;
6310 tANI_U8 maxSpeedMCS = 0;
6311 tANI_U8 maxMCSIdx = 0;
6312 tANI_U8 rateFlag = 1;
6313 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006314 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306315 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006316
Leo Chang6f8870f2013-03-26 18:11:36 -07006317#ifdef WLAN_FEATURE_11AC
6318 tANI_U32 vht_mcs_map;
6319 eDataRate11ACMaxMcs vhtMaxMcs;
6320#endif /* WLAN_FEATURE_11AC */
6321
Jeff Johnsone7245742012-09-05 17:12:55 -07006322 ENTER();
6323
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6325 (0 == ssidlen))
6326 {
6327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6328 " Invalid ssidlen, %d", __func__, ssidlen);
6329 /*To keep GUI happy*/
6330 return 0;
6331 }
6332
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306333 status = wlan_hdd_validate_context(pHddCtx);
6334
6335 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6338 "%s: HDD context is not valid", __func__);
6339 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006340 }
6341
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6343 sinfo->filled |= STATION_INFO_SIGNAL;
6344
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006345 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6347
6348 //convert to the UI units of 100kbps
6349 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6350
6351#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006352 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 -07006353 sinfo->signal,
6354 pCfg->reportMaxLinkSpeed,
6355 myRate,
6356 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006357 (int) pCfg->linkSpeedRssiMid,
6358 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006359 (int) rate_flags,
6360 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006361#endif //LINKSPEED_DEBUG_ENABLED
6362
6363 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6364 {
6365 // we do not want to necessarily report the current speed
6366 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6367 {
6368 // report the max possible speed
6369 rssidx = 0;
6370 }
6371 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6372 {
6373 // report the max possible speed with RSSI scaling
6374 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6375 {
6376 // report the max possible speed
6377 rssidx = 0;
6378 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006379 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 {
6381 // report middle speed
6382 rssidx = 1;
6383 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006384 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6385 {
6386 // report middle speed
6387 rssidx = 2;
6388 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 else
6390 {
6391 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006392 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 }
6394 }
6395 else
6396 {
6397 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6398 hddLog(VOS_TRACE_LEVEL_ERROR,
6399 "%s: Invalid value for reportMaxLinkSpeed: %u",
6400 __func__, pCfg->reportMaxLinkSpeed);
6401 rssidx = 0;
6402 }
6403
6404 maxRate = 0;
6405
6406 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306407 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6408 OperationalRates, &ORLeng))
6409 {
6410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6411 /*To keep GUI happy*/
6412 return 0;
6413 }
6414
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 for (i = 0; i < ORLeng; i++)
6416 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006417 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 {
6419 /* Validate Rate Set */
6420 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6421 {
6422 currentRate = supported_data_rate[j].supported_rate[rssidx];
6423 break;
6424 }
6425 }
6426 /* Update MAX rate */
6427 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6428 }
6429
6430 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306431 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6432 ExtendedRates, &ERLeng))
6433 {
6434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6435 /*To keep GUI happy*/
6436 return 0;
6437 }
6438
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 for (i = 0; i < ERLeng; i++)
6440 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006441 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 {
6443 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6444 {
6445 currentRate = supported_data_rate[j].supported_rate[rssidx];
6446 break;
6447 }
6448 }
6449 /* Update MAX rate */
6450 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6451 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 /* Get MCS Rate Set -- but only if we are connected at MCS
6453 rates or if we are always reporting max speed or if we have
6454 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006455 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306457 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6458 MCSRates, &MCSLeng))
6459 {
6460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6461 /*To keep GUI happy*/
6462 return 0;
6463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006465#ifdef WLAN_FEATURE_11AC
6466 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306467 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006469 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306470 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006471 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006473 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006475 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006477 maxMCSIdx = 7;
6478 }
6479 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6480 {
6481 maxMCSIdx = 8;
6482 }
6483 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6484 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306485 //VHT20 is supporting 0~8
6486 if (rate_flags & eHAL_TX_RATE_VHT20)
6487 maxMCSIdx = 8;
6488 else
6489 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006490 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306491
6492 if (rate_flags & eHAL_TX_RATE_VHT80)
6493 {
6494 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6495 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6496 }
6497 else if (rate_flags & eHAL_TX_RATE_VHT40)
6498 {
6499 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6500 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6501 }
6502 else if (rate_flags & eHAL_TX_RATE_VHT20)
6503 {
6504 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6505 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6506 }
6507
Leo Chang6f8870f2013-03-26 18:11:36 -07006508 maxSpeedMCS = 1;
6509 if (currentRate > maxRate)
6510 {
6511 maxRate = currentRate;
6512 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306513
Leo Chang6f8870f2013-03-26 18:11:36 -07006514 }
6515 else
6516#endif /* WLAN_FEATURE_11AC */
6517 {
6518 if (rate_flags & eHAL_TX_RATE_HT40)
6519 {
6520 rateFlag |= 1;
6521 }
6522 if (rate_flags & eHAL_TX_RATE_SGI)
6523 {
6524 rateFlag |= 2;
6525 }
6526
6527 for (i = 0; i < MCSLeng; i++)
6528 {
6529 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6530 for (j = 0; j < temp; j++)
6531 {
6532 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6533 {
6534 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6535 break;
6536 }
6537 }
6538 if ((j < temp) && (currentRate > maxRate))
6539 {
6540 maxRate = currentRate;
6541 maxSpeedMCS = 1;
6542 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 }
6545 }
6546 }
6547
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306548 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6549 {
6550 maxRate = myRate;
6551 maxSpeedMCS = 1;
6552 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6553 }
6554
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006556 if (((maxRate < myRate) && (0 == rssidx)) ||
6557 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 {
6559 maxRate = myRate;
6560 if (rate_flags & eHAL_TX_RATE_LEGACY)
6561 {
6562 maxSpeedMCS = 0;
6563 }
6564 else
6565 {
6566 maxSpeedMCS = 1;
6567 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6568 }
6569 }
6570
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306571 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 {
6573 sinfo->txrate.legacy = maxRate;
6574#ifdef LINKSPEED_DEBUG_ENABLED
6575 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6576#endif //LINKSPEED_DEBUG_ENABLED
6577 }
6578 else
6579 {
6580 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006581#ifdef WLAN_FEATURE_11AC
6582 sinfo->txrate.nss = 1;
6583 if (rate_flags & eHAL_TX_RATE_VHT80)
6584 {
6585 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306586 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006587 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306588 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006589 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306590 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6591 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6592 }
6593 else if (rate_flags & eHAL_TX_RATE_VHT20)
6594 {
6595 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6596 }
6597#endif /* WLAN_FEATURE_11AC */
6598 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6599 {
6600 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6601 if (rate_flags & eHAL_TX_RATE_HT40)
6602 {
6603 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6604 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 if (rate_flags & eHAL_TX_RATE_SGI)
6607 {
6608 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6609 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306610
Jeff Johnson295189b2012-06-20 16:38:30 -07006611#ifdef LINKSPEED_DEBUG_ENABLED
6612 pr_info("Reporting MCS rate %d flags %x\n",
6613 sinfo->txrate.mcs,
6614 sinfo->txrate.flags );
6615#endif //LINKSPEED_DEBUG_ENABLED
6616 }
6617 }
6618 else
6619 {
6620 // report current rate instead of max rate
6621
6622 if (rate_flags & eHAL_TX_RATE_LEGACY)
6623 {
6624 //provide to the UI in units of 100kbps
6625 sinfo->txrate.legacy = myRate;
6626#ifdef LINKSPEED_DEBUG_ENABLED
6627 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6628#endif //LINKSPEED_DEBUG_ENABLED
6629 }
6630 else
6631 {
6632 //must be MCS
6633 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006634#ifdef WLAN_FEATURE_11AC
6635 sinfo->txrate.nss = 1;
6636 if (rate_flags & eHAL_TX_RATE_VHT80)
6637 {
6638 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6639 }
6640 else
6641#endif /* WLAN_FEATURE_11AC */
6642 {
6643 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 if (rate_flags & eHAL_TX_RATE_SGI)
6646 {
6647 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6648 }
6649 if (rate_flags & eHAL_TX_RATE_HT40)
6650 {
6651 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6652 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006653#ifdef WLAN_FEATURE_11AC
6654 else if (rate_flags & eHAL_TX_RATE_VHT80)
6655 {
6656 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6657 }
6658#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006659#ifdef LINKSPEED_DEBUG_ENABLED
6660 pr_info("Reporting actual MCS rate %d flags %x\n",
6661 sinfo->txrate.mcs,
6662 sinfo->txrate.flags );
6663#endif //LINKSPEED_DEBUG_ENABLED
6664 }
6665 }
6666 sinfo->filled |= STATION_INFO_TX_BITRATE;
6667
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006668 sinfo->tx_packets =
6669 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6670 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6671 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6672 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6673
6674 sinfo->tx_retries =
6675 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6676 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6677 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6678 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6679
6680 sinfo->tx_failed =
6681 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6682 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6683 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6684 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6685
6686 sinfo->filled |=
6687 STATION_INFO_TX_PACKETS |
6688 STATION_INFO_TX_RETRIES |
6689 STATION_INFO_TX_FAILED;
6690
6691 EXIT();
6692 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006693}
6694
6695static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6696 struct net_device *dev, bool mode, v_SINT_t timeout)
6697{
6698 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306699 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306701 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006702
Jeff Johnsone7245742012-09-05 17:12:55 -07006703 ENTER();
6704
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 if (NULL == pAdapter)
6706 {
6707 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6708 return -ENODEV;
6709 }
6710
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306711 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306712 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306714 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306715 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6717 "%s: HDD context is not valid", __func__);
6718 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306719 }
6720
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306721 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6722 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6723 (pHddCtx->cfg_ini->fhostArpOffload) &&
6724 (eConnectionState_Associated ==
6725 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6726 {
6727 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6728 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6729 {
6730 hddLog(VOS_TRACE_LEVEL_INFO,
6731 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6732 __func__, vos_status);
6733 }
6734 }
6735
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 /**The get power cmd from the supplicant gets updated by the nl only
6737 *on successful execution of the function call
6738 *we are oppositely mapped w.r.t mode in the driver
6739 **/
6740 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6741
Jeff Johnsone7245742012-09-05 17:12:55 -07006742 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 if (VOS_STATUS_E_FAILURE == vos_status)
6744 {
6745 return -EINVAL;
6746 }
6747 return 0;
6748}
6749
6750
6751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6752static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6753 struct net_device *netdev,
6754 u8 key_index)
6755{
Jeff Johnsone7245742012-09-05 17:12:55 -07006756 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 return 0;
6758}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306759#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006760
6761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6762static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6763 struct net_device *dev,
6764 struct ieee80211_txq_params *params)
6765{
Jeff Johnsone7245742012-09-05 17:12:55 -07006766 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 return 0;
6768}
6769#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6770static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6771 struct ieee80211_txq_params *params)
6772{
Jeff Johnsone7245742012-09-05 17:12:55 -07006773 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 return 0;
6775}
6776#endif //LINUX_VERSION_CODE
6777
6778static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6779 struct net_device *dev, u8 *mac)
6780{
6781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306782 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006783 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306784 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006785 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006786
Jeff Johnsone7245742012-09-05 17:12:55 -07006787 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306788 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 return -EINVAL;
6792 }
6793
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6795 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006796
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306797 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006798 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6800 "%s: HDD context is not valid", __func__);
6801 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006802 }
6803
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 )
6807 {
6808 if( NULL == mac )
6809 {
6810 v_U16_t i;
6811 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6812 {
6813 if(pAdapter->aStaInfo[i].isUsed)
6814 {
6815 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6816 hddLog(VOS_TRACE_LEVEL_INFO,
6817 "%s: Delete STA with MAC::"
6818 "%02x:%02x:%02x:%02x:%02x:%02x",
6819 __func__,
6820 macAddr[0], macAddr[1], macAddr[2],
6821 macAddr[3], macAddr[4], macAddr[5]);
6822 hdd_softap_sta_deauth(pAdapter, macAddr);
6823 }
6824 }
6825 }
6826 else
6827 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006828
6829 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6830 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6831 {
6832 hddLog(VOS_TRACE_LEVEL_INFO,
6833 "%s: Skip this DEL STA as this is not used::"
6834 "%02x:%02x:%02x:%02x:%02x:%02x",
6835 __func__,
6836 mac[0], mac[1], mac[2],
6837 mac[3], mac[4], mac[5]);
6838 return -ENOENT;
6839 }
6840
6841 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6842 {
6843 hddLog(VOS_TRACE_LEVEL_INFO,
6844 "%s: Skip this DEL STA as deauth is in progress::"
6845 "%02x:%02x:%02x:%02x:%02x:%02x",
6846 __func__,
6847 mac[0], mac[1], mac[2],
6848 mac[3], mac[4], mac[5]);
6849 return -ENOENT;
6850 }
6851
6852 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6853
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 hddLog(VOS_TRACE_LEVEL_INFO,
6855 "%s: Delete STA with MAC::"
6856 "%02x:%02x:%02x:%02x:%02x:%02x",
6857 __func__,
6858 mac[0], mac[1], mac[2],
6859 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006860
6861 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6862 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6863 {
6864 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6865 hddLog(VOS_TRACE_LEVEL_INFO,
6866 "%s: STA removal failed for ::"
6867 "%02x:%02x:%02x:%02x:%02x:%02x",
6868 __func__,
6869 mac[0], mac[1], mac[2],
6870 mac[3], mac[4], mac[5]);
6871 return -ENOENT;
6872 }
6873
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 }
6875 }
6876
6877 EXIT();
6878
6879 return 0;
6880}
6881
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006882static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6883 struct net_device *dev, u8 *mac, struct station_parameters *params)
6884{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006885 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006886#ifdef FEATURE_WLAN_TDLS
6887 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006888 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006889 mask = params->sta_flags_mask;
6890
6891 set = params->sta_flags_set;
6892
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006893#ifdef WLAN_FEATURE_TDLS_DEBUG
6894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6895 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6896 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6897#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006898
6899 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6900 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006901 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006902 }
6903 }
6904#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006905 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006906}
6907
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006908
6909#ifdef FEATURE_WLAN_LFR
6910static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006911 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006912{
6913#define MAX_PMKSAIDS_IN_CACHE 8
6914 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 static tANI_U32 i; // HDD Local Cache index
6916 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6918 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306919 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306920 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006921 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306922 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306923
Jeff Johnsone7245742012-09-05 17:12:55 -07006924 ENTER();
6925
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306926 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306927 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006928 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006930 return -EINVAL;
6931 }
6932
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6934 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006935
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306936 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6939 "%s: HDD context is not valid", __func__);
6940 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006941 }
6942
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306943 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6945
6946 for (j = 0; j < i; j++)
6947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306948 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949 pmksa->bssid, WNI_CFG_BSSID_LEN))
6950 {
6951 /* BSSID matched previous entry. Overwrite it. */
6952 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306953 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006954 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306955 vos_mem_copy(PMKIDCache[j].PMKID,
6956 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306958 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006959 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006960 dump_bssid(pmksa->bssid);
6961 dump_pmkid(halHandle, pmksa->pmkid);
6962 break;
6963 }
6964 }
6965
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006966 /* Check we compared all entries,if then take the first slot now */
6967 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6968
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306970 {
6971 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6972 vos_mem_copy(PMKIDCache[i].BSSID,
6973 pmksa->bssid, ETHER_ADDR_LEN);
6974 vos_mem_copy(PMKIDCache[i].PMKID,
6975 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006976 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306977 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006978 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006979 dump_bssid(pmksa->bssid);
6980 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006982 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306983 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006984 }
6985
6986
6987 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306988 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006989 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306990 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006991 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306993 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6994 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006995 i );
6996 return 0;
6997}
6998
6999
7000static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007001 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007002{
Jeff Johnsone7245742012-09-05 17:12:55 -07007003 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007004 // TODO: Implement this later.
7005 return 0;
7006}
7007
7008static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7009{
Jeff Johnsone7245742012-09-05 17:12:55 -07007010 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007011 // TODO: Implement this later.
7012 return 0;
7013}
7014#endif
7015
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007016#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007018 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7019{
7020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7021 hdd_station_ctx_t *pHddStaCtx;
7022
7023 if (NULL == pAdapter)
7024 {
7025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7026 return -ENODEV;
7027 }
7028
7029 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7030
7031 // Added for debug on reception of Re-assoc Req.
7032 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307034 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007035 ftie->ie_len);
7036 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7037 }
7038
7039#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307040 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007041 ftie->ie_len);
7042#endif
7043
7044 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307045 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7046 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007047 ftie->ie_len);
7048 return 0;
7049}
7050#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007051
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307052#ifdef FEATURE_WLAN_SCAN_PNO
7053
7054void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7055 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7056{
7057 int ret;
7058 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7059 hdd_context_t *pHddCtx;
7060
7061 if (NULL == pAdapter)
7062 {
7063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7064 "%s: HDD adapter is Null", __func__);
7065 return ;
7066 }
7067
7068 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7069 if (NULL == pHddCtx)
7070 {
7071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7072 "%s: HDD context is Null!!!", __func__);
7073 return ;
7074 }
7075
7076 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7077
7078 if (0 > ret)
7079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7080
7081 cfg80211_sched_scan_results(pHddCtx->wiphy);
7082}
7083
7084/*
7085 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7086 * NL interface to enable PNO
7087 */
7088static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7089 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7090{
7091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7092 tpSirPNOScanReq pPnoRequest = NULL;
7093 hdd_context_t *pHddCtx;
7094 tHalHandle hHal;
7095 v_U32_t i, indx, num_ch;
7096 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7097 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7098 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7099 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307100 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307101
7102 if (NULL == pAdapter)
7103 {
7104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7105 "%s: HDD adapter is Null", __func__);
7106 return -ENODEV;
7107 }
7108
7109 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307110 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307111
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307112 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307113 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7115 "%s: HDD context is not valid", __func__);
7116 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307117 }
7118
7119 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7120 if (NULL == hHal)
7121 {
7122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7123 "%s: HAL context is Null!!!", __func__);
7124 return -EAGAIN;
7125 }
7126
7127 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7128 if (NULL == pPnoRequest)
7129 {
7130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7131 "%s: vos_mem_malloc failed", __func__);
7132 return -ENODEV;
7133 }
7134
7135 pPnoRequest->enable = 1; /*Enable PNO */
7136 pPnoRequest->ucNetworksCount = request->n_match_sets;
7137
7138 if (( !pPnoRequest->ucNetworksCount ) ||
7139 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7140 {
7141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7142 "Network input is not correct");
7143 goto error;
7144 }
7145
7146 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7147 {
7148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7149 "Incorrect number of channels");
7150 goto error;
7151 }
7152
7153 /* Framework provides one set of channels(all)
7154 * common for all saved profile */
7155 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7156 channels_allowed, &num_channels_allowed))
7157 {
7158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7159 "%s: failed to get valid channel list", __func__);
7160 goto error;
7161 }
7162 /* Checking each channel against allowed channel list */
7163 num_ch = 0;
7164 for (i = 0; i < request->n_channels; i++)
7165 {
7166 for (indx = 0; indx < num_channels_allowed; indx++)
7167 {
7168 if (request->channels[i]->hw_value == channels_allowed[indx])
7169 {
7170 valid_ch[num_ch++] = request->channels[i]->hw_value;
7171 break ;
7172 }
7173 }
7174 }
7175
7176 /* Filling per profile params */
7177 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7178 {
7179 pPnoRequest->aNetworks[i].ssId.length =
7180 request->match_sets[i].ssid.ssid_len;
7181
7182 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7183 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7184 {
7185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7186 "SSID Len %d is not correct for network %d",
7187 pPnoRequest->aNetworks[i].ssId.length, i);
7188 goto error;
7189 }
7190
7191 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7192 request->match_sets[i].ssid.ssid,
7193 request->match_sets[i].ssid.ssid_len);
7194 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7195 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7196 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7197
7198 /*Copying list of valid channel into request */
7199 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7200 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7201
7202 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7203 }
7204
7205 /* framework provides interval in ms */
7206 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7207 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7208 (request->interval)/1000;
7209 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7210 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7211
7212 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7213 pPnoRequest, pAdapter->sessionId,
7214 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7215 if (eHAL_STATUS_SUCCESS != status)
7216 {
7217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7218 "Failed to enable PNO");
7219 goto error;
7220 }
7221
7222error:
7223 vos_mem_free(pPnoRequest);
7224 return status;
7225}
7226
7227/*
7228 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7229 * NL interface to disable PNO
7230 */
7231static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7232 struct net_device *dev)
7233{
7234 eHalStatus status = eHAL_STATUS_FAILURE;
7235 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7236 hdd_context_t *pHddCtx;
7237 tHalHandle hHal;
7238 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307239 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307240
7241 ENTER();
7242
7243 if (NULL == pAdapter)
7244 {
7245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7246 "%s: HDD adapter is Null", __func__);
7247 return -ENODEV;
7248 }
7249
7250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307251 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307252
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307253 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307254 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7256 "%s: HDD context is not valid", __func__);
7257 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307258 }
7259
7260 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7261 if (NULL == hHal)
7262 {
7263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7264 "%s: HAL context is Null!!!", __func__);
7265 return -EAGAIN;
7266 }
7267
7268 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7269 if (NULL == pPnoRequest)
7270 {
7271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7272 "%s: vos_mem_malloc failed", __func__);
7273 return -ENODEV;
7274 }
7275
7276 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7277 pPnoRequest->enable = 0; /* Disable PNO */
7278 pPnoRequest->ucNetworksCount = 0;
7279
7280 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7281 pAdapter->sessionId,
7282 NULL, pAdapter);
7283 if (eHAL_STATUS_SUCCESS != status)
7284 {
7285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7286 "Failed to disabled PNO");
7287 }
7288
7289 vos_mem_free(pPnoRequest);
7290
7291 EXIT();
7292 return status;
7293}
7294
7295#endif /*FEATURE_WLAN_SCAN_PNO*/
7296
7297
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007298#ifdef FEATURE_WLAN_TDLS
7299static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7300 u8 *peer, u8 action_code, u8 dialog_token,
7301 u16 status_code, const u8 *buf, size_t len)
7302{
7303
7304 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7305 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007306 u8 peerMac[6];
7307 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007308 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007309 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007310 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007311
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007312 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007315 "Invalid arguments");
7316 return -EINVAL;
7317 }
7318
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007319 if (pHddCtx->isLogpInProgress)
7320 {
7321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7322 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007323 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007324 return -EBUSY;
7325 }
7326
Hoonki Lee27511902013-03-14 18:19:06 -07007327 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007328 {
Hoonki Lee27511902013-03-14 18:19:06 -07007329 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7330 "%s: TDLS mode is disabled OR not enabled in FW."
7331 MAC_ADDRESS_STR " action %d declined.",
7332 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007333 return -ENOTSUPP;
7334 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007335
Hoonki Lee27511902013-03-14 18:19:06 -07007336 /* other than teardown frame, other mgmt frames are not sent if disabled */
7337 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7338 {
7339 /* if tdls_mode is disabled to respond to peer's request */
7340 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7341 {
7342 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7343 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007344 " TDLS mode is disabled. action %d declined.",
7345 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007346
7347 return -ENOTSUPP;
7348 }
7349 }
7350
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007351 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7352 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007353 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007354 {
7355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007356 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007357 " TDLS setup is ongoing. action %d declined.",
7358 __func__, MAC_ADDR_ARRAY(peer), action_code);
7359 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007360 }
7361 }
7362
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007363 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7364 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007365 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007366 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007367 {
7368 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7369 we return error code at 'add_station()'. Hence we have this
7370 check again in addtion to add_station().
7371 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007372 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007373 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7375 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007376 " TDLS Max peer already connected. action %d declined.",
7377 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007378 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007379 }
7380 else
7381 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007382 /* maximum reached. tweak to send error code to peer and return
7383 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007384 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7386 "%s: " MAC_ADDRESS_STR
7387 " TDLS Max peer already connected send response status %d",
7388 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007389 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007390 /* fall through to send setup resp with failure status
7391 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007392 }
7393 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007394 else
7395 {
7396 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007397 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007398 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007399 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007401 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7402 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007403 return -EPERM;
7404 }
7405 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007406 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007407 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007408
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007409#ifdef WLAN_FEATURE_TDLS_DEBUG
7410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007411 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7412 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7413 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007414#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007415
Hoonki Leea34dd892013-02-05 22:56:02 -08007416 /*Except teardown responder will not be used so just make 0*/
7417 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007418 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007419 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007420
7421 hddTdlsPeer_t *pTdlsPeer;
7422 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7423
7424 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7425 responder = pTdlsPeer->is_responder;
7426 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007427 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7429 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7430 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7431 dialog_token, status_code, len);
7432 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007433 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007434 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007435
Hoonki Lee14621352013-04-16 17:51:19 -07007436 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7437 (SIR_MAC_TDLS_DIS_RSP == action_code))
7438 {
7439 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7440 {
7441 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7442 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7443 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7444 }
7445 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7446 }
7447
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007448 /* make sure doesn't call send_mgmt() while it is pending */
7449 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7450 {
7451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7452 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7453 __func__, MAC_ADDR_ARRAY(peer), action_code);
7454 return -EBUSY;
7455 }
7456
7457 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007458 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7459
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007460 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007461 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007462
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007463 if (VOS_STATUS_SUCCESS != status)
7464 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7466 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007467 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007468 wlan_hdd_tdls_check_bmps(pAdapter);
7469 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007470 }
7471
Hoonki Leed37cbb32013-04-20 00:31:14 -07007472 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7473 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7474
7475 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007476 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7478 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7479 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007480 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007481 wlan_hdd_tdls_check_bmps(pAdapter);
7482 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007483 }
7484
Gopichand Nakkala05922802013-03-14 12:23:19 -07007485 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007486 {
7487 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007488 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007489 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007490
Hoonki Leea34dd892013-02-05 22:56:02 -08007491 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7492 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007493 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007494 }
7495 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7496 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007497 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007498 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007499
7500 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007501error:
7502 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7503 because we already know that this transaction will be failed,
7504 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7505 to be safe, do not change the state mahine.
7506 */
7507 if(max_sta_failed == 0 &&
7508 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7509 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7510 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007511}
7512
7513static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7514 u8 *peer, enum nl80211_tdls_operation oper)
7515{
7516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7517 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307518 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307519#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7520 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307521 tANI_U8 staIdx;
7522#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007523#ifdef WLAN_FEATURE_TDLS_DEBUG
7524 const char *tdls_oper_str[]= {
7525 "NL80211_TDLS_DISCOVERY_REQ",
7526 "NL80211_TDLS_SETUP",
7527 "NL80211_TDLS_TEARDOWN",
7528 "NL80211_TDLS_ENABLE_LINK",
7529 "NL80211_TDLS_DISABLE_LINK",
7530 "NL80211_TDLS_UNKONW_OPER"};
7531#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007532 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007533
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307534 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007535 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007537 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007538 return -EINVAL;
7539 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007540
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307541 status = wlan_hdd_validate_context(pHddCtx);
7542
7543 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007544 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7546 "%s: HDD context is not valid", __func__);
7547 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007548 }
7549
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007550 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7551
7552 if ( NULL == pTdlsPeer ) {
7553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7554 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7555 return -EINVAL;
7556 }
7557
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007558#ifdef WLAN_FEATURE_TDLS_DEBUG
7559 if((int)oper > 4)
7560 oper = 5;
7561
7562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007563 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7564 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007565 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007566#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007567
7568 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007569 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007570 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007572 "TDLS Disabled in INI OR not enabled in FW. "
7573 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007574 return -ENOTSUPP;
7575 }
7576
7577 switch (oper) {
7578 case NL80211_TDLS_ENABLE_LINK:
7579 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007580 VOS_STATUS status;
7581
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007582 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7583 {
7584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7585 MAC_ADDRESS_STR " failed",
7586 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7587 return -EINVAL;
7588 }
7589
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007590 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007591 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007592 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007593 /* start TDLS client registration with TL */
7594 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007595 if (VOS_STATUS_SUCCESS == status)
7596 {
Hoonki Lee14621352013-04-16 17:51:19 -07007597 if (pTdlsPeer->is_responder == 0)
7598 {
7599 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7600
7601 wlan_hdd_tdls_timer_restart(pAdapter,
7602 &pTdlsPeer->initiatorWaitTimeoutTimer,
7603 WAIT_TIME_TDLS_INITIATOR);
7604 /* suspend initiator TX until it receives direct packet from the
7605 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7606 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7607 &staId, NULL);
7608 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007609 wlan_hdd_tdls_increment_peer_count(pAdapter);
7610 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007611 wlan_hdd_tdls_check_bmps(pAdapter);
7612 }
7613
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007614 }
7615 break;
7616 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007617 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007618 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007619 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007620 long status;
7621
7622 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7623
Lee Hoonkic1262f22013-01-24 21:59:00 -08007624 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7625 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007626
7627 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7628 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7629 if (status <= 0)
7630 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007631 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7633 "%s: Del station failed status %ld",
7634 __func__, status);
7635 return -EPERM;
7636 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007637 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007638 }
7639 else
7640 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7642 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007643 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307644#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7645 if (pHddTdlsCtx->defer_link_lost_indication)
7646 {
7647 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7648 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7649 {
7650 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7651 if ( 0 != status)
7652 {
7653 hddLog(VOS_TRACE_LEVEL_ERROR,
7654 "%s wlan_hdd_disconnect failure, returned %d \n",
7655 __func__, (int)status );
7656 return -EINVAL;
7657 }
7658 }
7659 }
7660#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007661 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007662 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007663 case NL80211_TDLS_TEARDOWN:
7664 case NL80211_TDLS_SETUP:
7665 case NL80211_TDLS_DISCOVERY_REQ:
7666 /* We don't support in-driver setup/teardown/discovery */
7667 return -ENOTSUPP;
7668 default:
7669 return -ENOTSUPP;
7670 }
7671 return 0;
7672}
Chilam NG571c65a2013-01-19 12:27:36 +05307673
7674int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7675 struct net_device *dev, u8 *peer)
7676{
7677 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7678 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7679
7680 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7681 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7682}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007683#endif
7684
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307685#ifdef WLAN_FEATURE_GTK_OFFLOAD
7686/*
7687 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7688 * Callback rountine called upon receiving response for
7689 * get offload info
7690 */
7691void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7692 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7693{
7694
7695 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7696
7697 ENTER();
7698
7699 if (NULL == pAdapter)
7700 {
7701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7702 "%s: HDD adapter is Null", __func__);
7703 return ;
7704 }
7705
7706 if (NULL == pGtkOffloadGetInfoRsp)
7707 {
7708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7709 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7710 return ;
7711 }
7712
7713 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7714 {
7715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7716 "%s: wlan Failed to get replay counter value",
7717 __func__);
7718 return ;
7719 }
7720
7721 /* Update replay counter to NL */
7722 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7723 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7724}
7725
7726/*
7727 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7728 * This function is used to offload GTK rekeying job to the firmware.
7729 */
7730int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7731 struct cfg80211_gtk_rekey_data *data)
7732{
7733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7734 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7735 hdd_station_ctx_t *pHddStaCtx;
7736 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307737 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307738 tpSirGtkOffloadParams pGtkOffloadReqParams;
7739 eHalStatus status = eHAL_STATUS_FAILURE;
7740
7741 ENTER();
7742
7743 if (NULL == pAdapter)
7744 {
7745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7746 "%s: HDD adapter is Null", __func__);
7747 return -ENODEV;
7748 }
7749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307750 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307751
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307752 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307753 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7755 "%s: HDD context is not valid", __func__);
7756 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307757 }
7758
7759 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7760 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7761 if (NULL == hHal)
7762 {
7763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7764 "%s: HAL context is Null!!!", __func__);
7765 return -EAGAIN;
7766 }
7767
7768 pGtkOffloadReqParams =
7769 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7770
7771 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7772 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7773 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7774 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7775 WNI_CFG_BSSID_LEN);
7776 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7777 sizeof (tANI_U64));
7778
7779 if (TRUE == pHddCtx->hdd_wlan_suspended)
7780 {
7781 /* if wlan is suspended, enable GTK offload directly from here */
7782 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7783 pAdapter->sessionId);
7784
7785 if (eHAL_STATUS_SUCCESS != status)
7786 {
7787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7788 "%s: sme_SetGTKOffload failed, returned %d",
7789 __func__, status);
7790 return status;
7791 }
7792 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7794 "%s: sme_SetGTKOffload successfull", __func__);
7795 }
7796 else
7797 {
7798 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7800 "%s: wlan not suspended GTKOffload request is stored",
7801 __func__);
7802 return eHAL_STATUS_SUCCESS;
7803 }
7804 return status;
7805}
7806#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7807
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307808/*
7809 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7810 * This function is used to set access control policy
7811 */
7812static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7813 struct net_device *dev, const struct cfg80211_acl_data *params)
7814{
7815 int i;
7816 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7817 hdd_hostapd_state_t *pHostapdState;
7818 tsap_Config_t *pConfig;
7819 v_CONTEXT_t pVosContext = NULL;
7820 hdd_context_t *pHddCtx;
7821 int status;
7822
7823 ENTER();
7824
7825 if (NULL == pAdapter)
7826 {
7827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7828 "%s: HDD adapter is Null", __func__);
7829 return -ENODEV;
7830 }
7831
7832 if (NULL == params)
7833 {
7834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7835 "%s: params is Null", __func__);
7836 return -EINVAL;
7837 }
7838
7839 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7840 status = wlan_hdd_validate_context(pHddCtx);
7841
7842 if (0 != status)
7843 {
7844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7845 "%s: HDD context is not valid", __func__);
7846 return status;
7847 }
7848
7849 pVosContext = pHddCtx->pvosContext;
7850 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7851
7852 if (NULL == pHostapdState)
7853 {
7854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7855 "%s: pHostapdState is Null", __func__);
7856 return -EINVAL;
7857 }
7858
7859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7860 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7861
7862 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7863 {
7864 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7865
7866 /* default value */
7867 pConfig->num_accept_mac = 0;
7868 pConfig->num_deny_mac = 0;
7869
7870 /**
7871 * access control policy
7872 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7873 * listed in hostapd.deny file.
7874 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7875 * listed in hostapd.accept file.
7876 */
7877 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7878 {
7879 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7880 }
7881 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
7882 {
7883 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7884 }
7885 else
7886 {
7887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7888 "%s:Acl Policy : %d is not supported",
7889 __func__, params->acl_policy);
7890 return -ENOTSUPP;
7891 }
7892
7893 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
7894 {
7895 pConfig->num_accept_mac = params->n_acl_entries;
7896 for (i = 0; i < params->n_acl_entries; i++)
7897 {
7898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7899 "** Add ACL MAC entry %i in WhiletList :"
7900 MAC_ADDRESS_STR, i,
7901 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7902
7903 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
7904 sizeof(qcmacaddr));
7905 }
7906 }
7907 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
7908 {
7909 pConfig->num_deny_mac = params->n_acl_entries;
7910 for (i = 0; i < params->n_acl_entries; i++)
7911 {
7912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7913 "** Add ACL MAC entry %i in BlackList :"
7914 MAC_ADDRESS_STR, i,
7915 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7916
7917 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
7918 sizeof(qcmacaddr));
7919 }
7920 }
7921
7922 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
7923 {
7924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7925 "%s: SAP Set Mac Acl fail", __func__);
7926 return -EINVAL;
7927 }
7928 }
7929 else
7930 {
7931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7932 "%s: Invalid device_mode = %d",
7933 __func__, pAdapter->device_mode);
7934 return -EINVAL;
7935 }
7936
7937 return 0;
7938}
7939
Jeff Johnson295189b2012-06-20 16:38:30 -07007940/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307941static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007942{
7943 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7944 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7945 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7946 .change_station = wlan_hdd_change_station,
7947#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7948 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7949 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7950 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007951#else
7952 .start_ap = wlan_hdd_cfg80211_start_ap,
7953 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7954 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007955#endif
7956 .change_bss = wlan_hdd_cfg80211_change_bss,
7957 .add_key = wlan_hdd_cfg80211_add_key,
7958 .get_key = wlan_hdd_cfg80211_get_key,
7959 .del_key = wlan_hdd_cfg80211_del_key,
7960 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 .scan = wlan_hdd_cfg80211_scan,
7965 .connect = wlan_hdd_cfg80211_connect,
7966 .disconnect = wlan_hdd_cfg80211_disconnect,
7967 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7968 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7969 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7970 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7971 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7973 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7974 .mgmt_tx = wlan_hdd_action,
7975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7976 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7977 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7978 .set_txq_params = wlan_hdd_set_txq_params,
7979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 .get_station = wlan_hdd_cfg80211_get_station,
7981 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7982 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007983 .add_station = wlan_hdd_cfg80211_add_station,
7984#ifdef FEATURE_WLAN_LFR
7985 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7986 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7987 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7988#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007989#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7990 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7991#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007992#ifdef FEATURE_WLAN_TDLS
7993 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7994 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7995#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307996#ifdef WLAN_FEATURE_GTK_OFFLOAD
7997 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7998#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307999#ifdef FEATURE_WLAN_SCAN_PNO
8000 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8001 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8002#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308003 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008004};
8005