blob: f9be803a7f3f21be396d49df1485891e8030cd75 [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{
Jeff Johnsone7245742012-09-05 17:12:55 -0700537 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700538 switch(eBand)
539 {
540 case eCSR_BAND_24:
541 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
542 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
543 break;
544 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700545 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700546 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
547 break;
548 case eCSR_BAND_ALL:
549 default:
550 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
551 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
552 }
553 return 0;
554}
555/*
556 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530557 * This function is called by hdd_wlan_startup()
558 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700559 * This function is used to initialize and register wiphy structure.
560 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530561int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 struct wiphy *wiphy,
563 hdd_config_t *pCfg
564 )
565{
Jeff Johnsone7245742012-09-05 17:12:55 -0700566 ENTER();
567
Jeff Johnson295189b2012-06-20 16:38:30 -0700568 /* Now bind the underlying wlan device with wiphy */
569 set_wiphy_dev(wiphy, dev);
570
571 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
572
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700573 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700576 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
577 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
578 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700579 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700580#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700581#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
582 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800583#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700584 || pCfg->isFastRoamIniFeatureEnabled
585#endif
586#ifdef FEATURE_WLAN_CCX
587 || pCfg->isCcxIniFeatureEnabled
588#endif
589 )
590 {
591 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
592 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800593#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800594#ifdef FEATURE_WLAN_TDLS
595 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
596 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
597#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530598#ifdef FEATURE_WLAN_SCAN_PNO
599 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
600 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
601 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
602#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800603
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700604 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
605 driver can still register regulatory callback and
606 it will get CRDA setting in wiphy->band[], but
607 driver need to determine what to do with both
608 regulatory settings */
609 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700610
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530611 wiphy->max_scan_ssids = MAX_SCAN_SSID;
612
Jeff Johnson295189b2012-06-20 16:38:30 -0700613 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
614
615 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700617 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 | BIT(NL80211_IFTYPE_P2P_CLIENT)
619 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700620 | BIT(NL80211_IFTYPE_AP);
621
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800623 if( pCfg->enableMCC )
624 {
625 /* Currently, supports up to two channels */
626 wlan_hdd_iface_combination.num_different_channels = 2;
627
628 if( !pCfg->allowMCCGODiffBI )
629 wlan_hdd_iface_combination.beacon_int_infra_match = true;
630
631 }
632 wiphy->iface_combinations = &wlan_hdd_iface_combination;
633 wiphy->n_iface_combinations = 1;
634#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800635
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 /* Before registering we need to update the ht capabilitied based
637 * on ini values*/
638 if( !pCfg->ShortGI20MhzEnable )
639 {
640 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
641 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
642 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
643 }
644
645 if( !pCfg->ShortGI40MhzEnable )
646 {
647 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
648 }
649
650 if( !pCfg->nChannelBondingMode5GHz )
651 {
652 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
653 }
654
655 /*Initialize band capability*/
656 switch(pCfg->nBandCapability)
657 {
658 case eCSR_BAND_24:
659 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
660 break;
661 case eCSR_BAND_5G:
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
664 break;
665 case eCSR_BAND_ALL:
666 default:
667 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
668 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
669 }
670 /*Initialise the supported cipher suite details*/
671 wiphy->cipher_suites = hdd_cipher_suites;
672 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
673
674 /*signal strength in mBm (100*dBm) */
675 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
676
677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700678 wiphy->max_remain_on_channel_duration = 1000;
679#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700680
681 /* Register our wiphy dev with cfg80211 */
682 if (0 > wiphy_register(wiphy))
683 {
684 /* print eror */
685 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
686 return -EIO;
687 }
688
689 EXIT();
690 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530691}
Jeff Johnson295189b2012-06-20 16:38:30 -0700692
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700693/* In this function we will try to get default country code from crda.
694 If the gCrdaDefaultCountryCode is configured in ini file,
695 we will try to call user space crda to get the regulatory settings for
696 that country. We will timeout if we can't get it from crda.
697 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
698*/
699int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
700{
701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
702 if (memcmp(pCfg->crdaDefaultCountryCode,
703 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
704 {
705 init_completion(&pHddCtx->driver_crda_req);
706 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
707 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
708 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700709 /* if the country is not found from current regulatory.bin,
710 fall back to world domain */
711 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
712 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700713 }
714 return 0;
715}
716
Jeff Johnson295189b2012-06-20 16:38:30 -0700717/* In this function we will do all post VOS start initialization.
718 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530719 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700720*/
721void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
722{
Jeff Johnson295189b2012-06-20 16:38:30 -0700723 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
724 /* Register for all P2P action, public action etc frames */
725 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
726
Jeff Johnsone7245742012-09-05 17:12:55 -0700727 ENTER();
728
Jeff Johnson295189b2012-06-20 16:38:30 -0700729 /* Right now we are registering these frame when driver is getting
730 initialized. Once we will move to 2.6.37 kernel, in which we have
731 frame register ops, we will move this code as a part of that */
732 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530733 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700734 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
735
736 /* GAS Initial Response */
737 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
738 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530739
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 /* GAS Comeback Request */
741 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
742 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
743
744 /* GAS Comeback Response */
745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
746 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
747
748 /* P2P Public Action */
749 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530750 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700751 P2P_PUBLIC_ACTION_FRAME_SIZE );
752
753 /* P2P Action */
754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
755 (v_U8_t*)P2P_ACTION_FRAME,
756 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700757
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530758 /* WNM BSS Transition Request frame */
759 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
760 (v_U8_t*)WNM_BSS_ACTION_FRAME,
761 WNM_BSS_ACTION_FRAME_SIZE );
762
Chet Lanctot186b5732013-03-18 10:26:30 -0700763#ifdef WLAN_FEATURE_11W
764 /* SA Query Response Action Frame */
765 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
766 (v_U8_t*)SA_QUERY_FRAME_RSP,
767 SA_QUERY_FRAME_RSP_SIZE );
768#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700769}
770
771void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
772{
Jeff Johnson295189b2012-06-20 16:38:30 -0700773 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
774 /* Register for all P2P action, public action etc frames */
775 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
776
Jeff Johnsone7245742012-09-05 17:12:55 -0700777 ENTER();
778
Jeff Johnson295189b2012-06-20 16:38:30 -0700779 /* Right now we are registering these frame when driver is getting
780 initialized. Once we will move to 2.6.37 kernel, in which we have
781 frame register ops, we will move this code as a part of that */
782 /* GAS Initial Request */
783
784 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
785 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
786
787 /* GAS Initial Response */
788 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
789 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530790
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 /* GAS Comeback Request */
792 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
793 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
794
795 /* GAS Comeback Response */
796 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
797 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
798
799 /* P2P Public Action */
800 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530801 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 P2P_PUBLIC_ACTION_FRAME_SIZE );
803
804 /* P2P Action */
805 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
806 (v_U8_t*)P2P_ACTION_FRAME,
807 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700808
809#ifdef WLAN_FEATURE_11W
810 /* SA Query Response Action Frame */
811 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
812 (v_U8_t*)SA_QUERY_FRAME_RSP,
813 SA_QUERY_FRAME_RSP_SIZE );
814#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700815}
816
817#ifdef FEATURE_WLAN_WAPI
818void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
819 const u8 *mac_addr, u8 *key , int key_Len)
820{
821 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
822 tCsrRoamSetKey setKey;
823 v_BOOL_t isConnected = TRUE;
824 int status = 0;
825 v_U32_t roamId= 0xFF;
826 tANI_U8 *pKeyPtr = NULL;
827 int n = 0;
828
829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
830 __func__,pAdapter->device_mode);
831
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530832 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 setKey.keyId = key_index; // Store Key ID
834 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
835 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
836 setKey.paeRole = 0 ; // the PAE role
837 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
838 {
839 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
840 }
841 else
842 {
843 isConnected = hdd_connIsConnected(pHddStaCtx);
844 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
845 }
846 setKey.keyLength = key_Len;
847 pKeyPtr = setKey.Key;
848 memcpy( pKeyPtr, key, key_Len);
849
850 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
851 __func__, key_Len);
852 for (n = 0 ; n < key_Len; n++)
853 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
854 __func__,n,setKey.Key[n]);
855
856 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
857 if ( isConnected )
858 {
859 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
860 pAdapter->sessionId, &setKey, &roamId );
861 }
862 if ( status != 0 )
863 {
864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
865 "[%4d] sme_RoamSetKey returned ERROR status= %d",
866 __LINE__, status );
867 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
868 }
869}
870#endif /* FEATURE_WLAN_WAPI*/
871
872#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530873int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 beacon_data_t **ppBeacon,
875 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700876#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530877int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700878 beacon_data_t **ppBeacon,
879 struct cfg80211_beacon_data *params,
880 int dtim_period)
881#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530882{
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 int size;
884 beacon_data_t *beacon = NULL;
885 beacon_data_t *old = NULL;
886 int head_len,tail_len;
887
Jeff Johnsone7245742012-09-05 17:12:55 -0700888 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700889 if (params->head && !params->head_len)
890 return -EINVAL;
891
892 old = pAdapter->sessionCtx.ap.beacon;
893
894 if (!params->head && !old)
895 return -EINVAL;
896
897 if (params->tail && !params->tail_len)
898 return -EINVAL;
899
900#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
901 /* Kernel 3.0 is not updating dtim_period for set beacon */
902 if (!params->dtim_period)
903 return -EINVAL;
904#endif
905
906 if(params->head)
907 head_len = params->head_len;
908 else
909 head_len = old->head_len;
910
911 if(params->tail || !old)
912 tail_len = params->tail_len;
913 else
914 tail_len = old->tail_len;
915
916 size = sizeof(beacon_data_t) + head_len + tail_len;
917
918 beacon = kzalloc(size, GFP_KERNEL);
919
920 if( beacon == NULL )
921 return -ENOMEM;
922
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700923#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 if(params->dtim_period || !old )
925 beacon->dtim_period = params->dtim_period;
926 else
927 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700928#else
929 if(dtim_period || !old )
930 beacon->dtim_period = dtim_period;
931 else
932 beacon->dtim_period = old->dtim_period;
933#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530934
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
936 beacon->tail = beacon->head + head_len;
937 beacon->head_len = head_len;
938 beacon->tail_len = tail_len;
939
940 if(params->head) {
941 memcpy (beacon->head,params->head,beacon->head_len);
942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530943 else {
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 if(old)
945 memcpy (beacon->head,old->head,beacon->head_len);
946 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530947
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 if(params->tail) {
949 memcpy (beacon->tail,params->tail,beacon->tail_len);
950 }
951 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530952 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 memcpy (beacon->tail,old->tail,beacon->tail_len);
954 }
955
956 *ppBeacon = beacon;
957
958 kfree(old);
959
960 return 0;
961
962}
Jeff Johnson295189b2012-06-20 16:38:30 -0700963
964v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
965{
966 int left = length;
967 v_U8_t *ptr = pIes;
968 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530969
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530971 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 elem_id = ptr[0];
973 elem_len = ptr[1];
974 left -= 2;
975 if(elem_len > left)
976 {
977 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700978 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700979 eid,elem_len,left);
980 return NULL;
981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530982 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 {
984 return ptr;
985 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530986
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 left -= elem_len;
988 ptr += (elem_len + 2);
989 }
990 return NULL;
991}
992
Jeff Johnson295189b2012-06-20 16:38:30 -0700993/* Check if rate is 11g rate or not */
994static int wlan_hdd_rate_is_11g(u8 rate)
995{
996 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
997 u8 i;
998 for (i = 0; i < 8; i++)
999 {
1000 if(rate == gRateArray[i])
1001 return TRUE;
1002 }
1003 return FALSE;
1004}
1005
1006/* Check for 11g rate and set proper 11g only mode */
1007static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1008 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1009{
1010 u8 i, num_rates = pIe[0];
1011
1012 pIe += 1;
1013 for ( i = 0; i < num_rates; i++)
1014 {
1015 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1016 {
1017 /* If rate set have 11g rate than change the mode to 11G */
1018 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1019 if (pIe[i] & BASIC_RATE_MASK)
1020 {
1021 /* If we have 11g rate as basic rate, it means mode
1022 is 11g only mode.
1023 */
1024 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1025 *pCheckRatesfor11g = FALSE;
1026 }
1027 }
1028 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1029 {
1030 *require_ht = TRUE;
1031 }
1032 }
1033 return;
1034}
1035
1036static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1037{
1038 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1039 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1040 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1041 u8 checkRatesfor11g = TRUE;
1042 u8 require_ht = FALSE;
1043 u8 *pIe=NULL;
1044
1045 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1046
1047 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1048 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1049 if (pIe != NULL)
1050 {
1051 pIe += 1;
1052 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1053 &pConfig->SapHw_mode);
1054 }
1055
1056 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1057 WLAN_EID_EXT_SUPP_RATES);
1058 if (pIe != NULL)
1059 {
1060
1061 pIe += 1;
1062 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1063 &pConfig->SapHw_mode);
1064 }
1065
1066 if( pConfig->channel > 14 )
1067 {
1068 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1069 }
1070
1071 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1072 WLAN_EID_HT_CAPABILITY);
1073
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301074 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001075 {
1076 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1077 if(require_ht)
1078 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1079 }
1080}
1081
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301082static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1083 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1084{
1085 v_U8_t ielen = 0;
1086 v_U8_t *pIe = NULL;
1087 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1088
1089 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1090 pBeacon->tail, pBeacon->tail_len);
1091
1092 if (pIe)
1093 {
1094 ielen = pIe[1] + 2;
1095 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1096 {
1097 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1098 }
1099 else
1100 {
1101 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1102 return -EINVAL;
1103 }
1104 *total_ielen += ielen;
1105 }
1106 return 0;
1107}
1108
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001109#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001110static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1111 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001112#else
1113static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1114 struct cfg80211_beacon_data *params)
1115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001116{
1117 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301118 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001120 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
1122 genie = vos_mem_malloc(MAX_GENIE_LEN);
1123
1124 if(genie == NULL) {
1125
1126 return -ENOMEM;
1127 }
1128
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301129 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1130 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301132 ret = -EINVAL;
1133 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 }
1135
1136#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301137 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1138 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1139 {
1140 ret = -EINVAL;
1141 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001142 }
1143#endif
1144
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301145 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1146 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301148 ret = -EINVAL;
1149 goto done;
1150 }
1151
1152 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1153 {
1154 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1155 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001156 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301157 ret = -EINVAL;
1158 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001159 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001161
1162 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1163 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1164 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1165 {
1166 hddLog(LOGE,
1167 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001168 ret = -EINVAL;
1169 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001170 }
1171
1172 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1173 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1174 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1175 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1176 ==eHAL_STATUS_FAILURE)
1177 {
1178 hddLog(LOGE,
1179 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001180 ret = -EINVAL;
1181 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 }
1183
1184 // Added for ProResp IE
1185 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1186 {
1187 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1188 u8 probe_rsp_ie_len[3] = {0};
1189 u8 counter = 0;
1190 /* Check Probe Resp Length if it is greater then 255 then Store
1191 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1192 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1193 Store More then 255 bytes into One Variable.
1194 */
1195 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1196 {
1197 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1198 {
1199 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1200 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1201 }
1202 else
1203 {
1204 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1205 rem_probe_resp_ie_len = 0;
1206 }
1207 }
1208
1209 rem_probe_resp_ie_len = 0;
1210
1211 if (probe_rsp_ie_len[0] > 0)
1212 {
1213 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1214 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1215 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1216 probe_rsp_ie_len[0], NULL,
1217 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1218 {
1219 hddLog(LOGE,
1220 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001221 ret = -EINVAL;
1222 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 }
1224 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1225 }
1226
1227 if (probe_rsp_ie_len[1] > 0)
1228 {
1229 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1230 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1231 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1232 probe_rsp_ie_len[1], NULL,
1233 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1234 {
1235 hddLog(LOGE,
1236 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001237 ret = -EINVAL;
1238 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 }
1240 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1241 }
1242
1243 if (probe_rsp_ie_len[2] > 0)
1244 {
1245 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1246 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1247 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1248 probe_rsp_ie_len[2], NULL,
1249 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1250 {
1251 hddLog(LOGE,
1252 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001253 ret = -EINVAL;
1254 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 }
1256 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1257 }
1258
1259 if (probe_rsp_ie_len[1] == 0 )
1260 {
1261 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1262 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1263 eANI_BOOLEAN_FALSE) )
1264 {
1265 hddLog(LOGE,
1266 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1267 }
1268 }
1269
1270 if (probe_rsp_ie_len[2] == 0 )
1271 {
1272 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1273 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1274 eANI_BOOLEAN_FALSE) )
1275 {
1276 hddLog(LOGE,
1277 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1278 }
1279 }
1280
1281 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1282 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1283 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1284 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1285 == eHAL_STATUS_FAILURE)
1286 {
1287 hddLog(LOGE,
1288 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001289 ret = -EINVAL;
1290 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001291 }
1292 }
1293 else
1294 {
1295 // Reset WNI_CFG_PROBE_RSP Flags
1296 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1297
1298 hddLog(VOS_TRACE_LEVEL_INFO,
1299 "%s: No Probe Response IE received in set beacon",
1300 __func__);
1301 }
1302
1303 // Added for AssocResp IE
1304 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1305 {
1306 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1307 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1308 params->assocresp_ies_len, NULL,
1309 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1310 {
1311 hddLog(LOGE,
1312 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001313 ret = -EINVAL;
1314 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001315 }
1316
1317 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1318 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1319 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1320 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1321 == eHAL_STATUS_FAILURE)
1322 {
1323 hddLog(LOGE,
1324 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001325 ret = -EINVAL;
1326 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 }
1328 }
1329 else
1330 {
1331 hddLog(VOS_TRACE_LEVEL_INFO,
1332 "%s: No Assoc Response IE received in set beacon",
1333 __func__);
1334
1335 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1336 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1337 eANI_BOOLEAN_FALSE) )
1338 {
1339 hddLog(LOGE,
1340 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1341 }
1342 }
1343
Jeff Johnsone7245742012-09-05 17:12:55 -07001344done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001345 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301346 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001347}
Jeff Johnson295189b2012-06-20 16:38:30 -07001348
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301349/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001350 * FUNCTION: wlan_hdd_validate_operation_channel
1351 * called by wlan_hdd_cfg80211_start_bss() and
1352 * wlan_hdd_cfg80211_set_channel()
1353 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301354 * channel list.
1355 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001356static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1357{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301358
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 v_U32_t num_ch = 0;
1360 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1361 u32 indx = 0;
1362 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301363 v_U8_t fValidChannel = FALSE, count = 0;
1364 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301365
Jeff Johnson295189b2012-06-20 16:38:30 -07001366 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1367
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301368 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301370 /* Validate the channel */
1371 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001372 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301373 if ( channel == rfChannels[count].channelNum )
1374 {
1375 fValidChannel = TRUE;
1376 break;
1377 }
1378 }
1379 if (fValidChannel != TRUE)
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 "%s: Invalid Channel [%d]", __func__, channel);
1383 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 }
1385 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301386 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001387 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301388 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1389 valid_ch, &num_ch))
1390 {
1391 hddLog(VOS_TRACE_LEVEL_ERROR,
1392 "%s: failed to get valid channel list", __func__);
1393 return VOS_STATUS_E_FAILURE;
1394 }
1395 for (indx = 0; indx < num_ch; indx++)
1396 {
1397 if (channel == valid_ch[indx])
1398 {
1399 break;
1400 }
1401 }
1402
1403 if (indx >= num_ch)
1404 {
1405 hddLog(VOS_TRACE_LEVEL_ERROR,
1406 "%s: Invalid Channel [%d]", __func__, channel);
1407 return VOS_STATUS_E_FAILURE;
1408 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 }
1410 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301411
Jeff Johnson295189b2012-06-20 16:38:30 -07001412}
1413
Viral Modi3a32cc52013-02-08 11:14:52 -08001414/**
1415 * FUNCTION: wlan_hdd_cfg80211_set_channel
1416 * This function is used to set the channel number
1417 */
1418static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1419 struct ieee80211_channel *chan,
1420 enum nl80211_channel_type channel_type
1421 )
1422{
1423 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001424 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001425 hdd_adapter_t *pAdapter = NULL;
1426 int freq = chan->center_freq; /* freq is in MHZ */
1427
1428 ENTER();
1429
1430 if( NULL == dev )
1431 {
1432 hddLog(VOS_TRACE_LEVEL_ERROR,
1433 "%s: Called with dev = NULL.\n", __func__);
1434 return -ENODEV;
1435 }
1436 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1437
1438 hddLog(VOS_TRACE_LEVEL_INFO,
1439 "%s: device_mode = %d freq = %d \n",__func__,
1440 pAdapter->device_mode, chan->center_freq);
1441 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1442 {
1443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1444 return -EAGAIN;
1445 }
1446
1447 /*
1448 * Do freq to chan conversion
1449 * TODO: for 11a
1450 */
1451
1452 channel = ieee80211_frequency_to_channel(freq);
1453
1454 /* Check freq range */
1455 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1456 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1457 {
1458 hddLog(VOS_TRACE_LEVEL_ERROR,
1459 "%s: Channel [%d] is outside valid range from %d to %d\n",
1460 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1461 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1462 return -EINVAL;
1463 }
1464
1465 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1466
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301467 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1468 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001469 {
1470 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1471 {
1472 hddLog(VOS_TRACE_LEVEL_ERROR,
1473 "%s: Invalid Channel [%d] \n", __func__, channel);
1474 return -EINVAL;
1475 }
1476 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1477 "%s: set channel to [%d] for device mode =%d",
1478 __func__, channel,pAdapter->device_mode);
1479 }
1480 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001481 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001482 )
1483 {
1484 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1485 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1486 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1487
1488 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1489 {
1490 /* Link is up then return cant set channel*/
1491 hddLog( VOS_TRACE_LEVEL_ERROR,
1492 "%s: IBSS Associated, can't set the channel\n", __func__);
1493 return -EINVAL;
1494 }
1495
1496 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1497 pHddStaCtx->conn_info.operationChannel = channel;
1498 pRoamProfile->ChannelInfo.ChannelList =
1499 &pHddStaCtx->conn_info.operationChannel;
1500 }
1501 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001502 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001503 )
1504 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301505 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1506 {
1507 if(VOS_STATUS_SUCCESS !=
1508 wlan_hdd_validate_operation_channel(pAdapter,channel))
1509 {
1510 hddLog(VOS_TRACE_LEVEL_ERROR,
1511 "%s: Invalid Channel [%d] \n", __func__, channel);
1512 return -EINVAL;
1513 }
1514 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1515 }
1516 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001517 {
1518 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1519
1520 /* If auto channel selection is configured as enable/ 1 then ignore
1521 channel set by supplicant
1522 */
1523 if ( cfg_param->apAutoChannelSelection )
1524 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301525 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1526 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001527 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1528 "%s: set channel to auto channel (0) for device mode =%d",
1529 __func__, pAdapter->device_mode);
1530 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301531 else
1532 {
1533 if(VOS_STATUS_SUCCESS !=
1534 wlan_hdd_validate_operation_channel(pAdapter,channel))
1535 {
1536 hddLog(VOS_TRACE_LEVEL_ERROR,
1537 "%s: Invalid Channel [%d] \n", __func__, channel);
1538 return -EINVAL;
1539 }
1540 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1541 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001542 }
1543 }
1544 else
1545 {
1546 hddLog(VOS_TRACE_LEVEL_FATAL,
1547 "%s: Invalid device mode failed to set valid channel", __func__);
1548 return -EINVAL;
1549 }
1550 EXIT();
1551 return 0;
1552}
1553
Jeff Johnson295189b2012-06-20 16:38:30 -07001554#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1555static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1556 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001557#else
1558static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1559 struct cfg80211_beacon_data *params,
1560 const u8 *ssid, size_t ssid_len,
1561 enum nl80211_hidden_ssid hidden_ssid)
1562#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001563{
1564 tsap_Config_t *pConfig;
1565 beacon_data_t *pBeacon = NULL;
1566 struct ieee80211_mgmt *pMgmt_frame;
1567 v_U8_t *pIe=NULL;
1568 v_U16_t capab_info;
1569 eCsrAuthType RSNAuthType;
1570 eCsrEncryptionType RSNEncryptType;
1571 eCsrEncryptionType mcRSNEncryptType;
1572 int status = VOS_STATUS_SUCCESS;
1573 tpWLAN_SAPEventCB pSapEventCallback;
1574 hdd_hostapd_state_t *pHostapdState;
1575 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1576 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301577 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001578 struct qc_mac_acl_entry *acl_entry = NULL;
1579 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001580 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001581
1582 ENTER();
1583
1584 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1585
1586 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1587
1588 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1589
1590 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1591
1592 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1593
1594 //channel is already set in the set_channel Call back
1595 //pConfig->channel = pCommitConfig->channel;
1596
1597 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301598 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1600
1601 pConfig->dtim_period = pBeacon->dtim_period;
1602
1603 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1604 pConfig->dtim_period);
1605
1606
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001607 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001608 {
1609 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001610 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001611 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001612 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001613 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001614 pConfig->ieee80211d = 1;
1615 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1616 sme_setRegInfo(hHal, pConfig->countryCode);
1617 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001619 else
1620 {
1621 pConfig->ieee80211d = 0;
1622 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301623 /*
1624 * If auto channel is configured i.e. channel is 0,
1625 * so skip channel validation.
1626 */
1627 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1628 {
1629 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1630 {
1631 hddLog(VOS_TRACE_LEVEL_ERROR,
1632 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1633 return -EINVAL;
1634 }
1635 }
1636 else
1637 {
1638 if(1 != pHddCtx->is_dynamic_channel_range_set)
1639 {
1640 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1641 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1642 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1643 }
1644 pHddCtx->is_dynamic_channel_range_set = 0;
1645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001647 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 {
1649 pConfig->ieee80211d = 0;
1650 }
1651 pConfig->authType = eSAP_AUTO_SWITCH;
1652
1653 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301654
1655 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1657
1658 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1659
1660 /*Set wps station to configured*/
1661 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1662
1663 if(pIe)
1664 {
1665 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1666 {
1667 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1668 return -EINVAL;
1669 }
1670 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1671 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001672 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 /* Check 15 bit of WPS IE as it contain information for wps state
1674 * WPS state
1675 */
1676 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1677 {
1678 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1679 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1680 {
1681 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1682 }
1683 }
1684 }
1685 else
1686 {
1687 pConfig->wps_state = SAP_WPS_DISABLED;
1688 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301689 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001690
1691 pConfig->RSNWPAReqIELength = 0;
1692 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301693 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001694 WLAN_EID_RSN);
1695 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301696 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001697 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1698 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1699 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301700 /* The actual processing may eventually be more extensive than
1701 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001702 * by the app.
1703 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301704 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001705 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1706 &RSNEncryptType,
1707 &mcRSNEncryptType,
1708 &RSNAuthType,
1709 pConfig->pRSNWPAReqIE[1]+2,
1710 pConfig->pRSNWPAReqIE );
1711
1712 if( VOS_STATUS_SUCCESS == status )
1713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301714 /* Now copy over all the security attributes you have
1715 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 * */
1717 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1718 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1719 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1720 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301721 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 "EncryptionType = %d mcEncryptionType = %d\n"),
1723 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1724 }
1725 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301726
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1728 pBeacon->tail, pBeacon->tail_len);
1729
1730 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1731 {
1732 if (pConfig->pRSNWPAReqIE)
1733 {
1734 /*Mixed mode WPA/WPA2*/
1735 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1736 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1737 }
1738 else
1739 {
1740 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1741 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1742 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301743 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001744 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1745 &RSNEncryptType,
1746 &mcRSNEncryptType,
1747 &RSNAuthType,
1748 pConfig->pRSNWPAReqIE[1]+2,
1749 pConfig->pRSNWPAReqIE );
1750
1751 if( VOS_STATUS_SUCCESS == status )
1752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301753 /* Now copy over all the security attributes you have
1754 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001755 * */
1756 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1757 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1758 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1759 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301760 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 "EncryptionType = %d mcEncryptionType = %d\n"),
1762 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1763 }
1764 }
1765 }
1766
Jeff Johnson4416a782013-03-25 14:17:50 -07001767 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1768 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1769 return -EINVAL;
1770 }
1771
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1773
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 if (params->ssid != NULL)
1776 {
1777 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1778 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1779 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1780 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1781 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001782#else
1783 if (ssid != NULL)
1784 {
1785 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1786 pConfig->SSIDinfo.ssid.length = ssid_len;
1787 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1788 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1789 }
1790#endif
1791
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301792 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301794
Jeff Johnson295189b2012-06-20 16:38:30 -07001795 /* default value */
1796 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1797 pConfig->num_accept_mac = 0;
1798 pConfig->num_deny_mac = 0;
1799
1800 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1801 pBeacon->tail, pBeacon->tail_len);
1802
1803 /* pIe for black list is following form:
1804 type : 1 byte
1805 length : 1 byte
1806 OUI : 4 bytes
1807 acl type : 1 byte
1808 no of mac addr in black list: 1 byte
1809 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301810 */
1811 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001812 {
1813 pConfig->SapMacaddr_acl = pIe[6];
1814 pConfig->num_deny_mac = pIe[7];
1815 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1816 pIe[6], pIe[7]);
1817 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1818 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1819 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1820 for (i = 0; i < pConfig->num_deny_mac; i++)
1821 {
1822 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1823 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 }
1826 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1827 pBeacon->tail, pBeacon->tail_len);
1828
1829 /* pIe for white list is following form:
1830 type : 1 byte
1831 length : 1 byte
1832 OUI : 4 bytes
1833 acl type : 1 byte
1834 no of mac addr in white list: 1 byte
1835 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301836 */
1837 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001838 {
1839 pConfig->SapMacaddr_acl = pIe[6];
1840 pConfig->num_accept_mac = pIe[7];
1841 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1842 pIe[6], pIe[7]);
1843 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1844 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1845 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1846 for (i = 0; i < pConfig->num_accept_mac; i++)
1847 {
1848 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1849 acl_entry++;
1850 }
1851 }
1852 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1853
Jeff Johnsone7245742012-09-05 17:12:55 -07001854#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001855 /* Overwrite the hostapd setting for HW mode only for 11ac.
1856 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1857 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1858 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1859 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301860 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001861 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1862 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001863 {
1864 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1865 }
1866#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301867
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001868 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1869 {
1870 sme_SelectCBMode(hHal,
1871 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1872 pConfig->channel);
1873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001874 // ht_capab is not what the name conveys,this is used for protection bitmap
1875 pConfig->ht_capab =
1876 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1877
1878 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1879 {
1880 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1881 return -EINVAL;
1882 }
1883
1884 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301885 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001886 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1887 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301888 pConfig->obssProtEnabled =
1889 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001890
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301891 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301893 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1895 (int)pConfig->channel);
1896 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301897 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1898 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301900 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001901 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1902 pConfig->protEnabled, pConfig->obssProtEnabled);
1903
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301904 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 {
1906 //Bss already started. just return.
1907 //TODO Probably it should update some beacon params.
1908 hddLog( LOGE, "Bss Already started...Ignore the request");
1909 EXIT();
1910 return 0;
1911 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301912
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 pConfig->persona = pHostapdAdapter->device_mode;
1914
1915 pSapEventCallback = hdd_hostapd_SAPEventCB;
1916 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1917 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1918 {
1919 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1920 return -EINVAL;
1921 }
1922
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301923 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1925
1926 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301927
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301929 {
1930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 ("ERROR: HDD vos wait for single_event failed!!\n"));
1932 VOS_ASSERT(0);
1933 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301934
Jeff Johnson295189b2012-06-20 16:38:30 -07001935 //Succesfully started Bss update the state bit.
1936 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1937
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001938#ifdef WLAN_FEATURE_P2P_DEBUG
1939 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1940 {
1941 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
1942 {
1943 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1944 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001945 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001946 }
1947 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
1948 {
1949 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
1950 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08001951 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001952 }
1953 }
1954#endif
1955
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 pHostapdState->bCommit = TRUE;
1957 EXIT();
1958
1959 return 0;
1960}
1961
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001962#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301963static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
1964 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 struct beacon_parameters *params)
1966{
1967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301968 int status=VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001969
1970 ENTER();
1971
1972 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
1973
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001974 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
1975 {
1976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1977 "%s:LOGP in Progress. Ignore!!!", __func__);
1978 return -EAGAIN;
1979 }
1980
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301981 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07001983 )
1984 {
1985 beacon_data_t *old,*new;
1986
1987 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989 if (old)
1990 return -EALREADY;
1991
1992 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
1993
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301994 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 {
1996 hddLog(VOS_TRACE_LEVEL_FATAL,
1997 "%s:Error!!! Allocating the new beacon\n",__func__);
1998 return -EINVAL;
1999 }
2000
2001 pAdapter->sessionCtx.ap.beacon = new;
2002
2003 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2004 }
2005
2006 EXIT();
2007 return status;
2008}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302009
2010static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 struct net_device *dev,
2012 struct beacon_parameters *params)
2013{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 int status=VOS_STATUS_SUCCESS;
2016
2017 ENTER();
2018
2019 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2020 __func__,pAdapter->device_mode);
2021
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002022 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2023 {
2024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2025 "%s:LOGP in Progress. Ignore!!!", __func__);
2026 return -EAGAIN;
2027 }
2028
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002030 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302031 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 {
2033 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302034
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302036
Jeff Johnson295189b2012-06-20 16:38:30 -07002037 if (!old)
2038 return -ENOENT;
2039
2040 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2041
2042 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302043 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 "%s: Error!!! Allocating the new beacon\n",__func__);
2045 return -EINVAL;
2046 }
2047
2048 pAdapter->sessionCtx.ap.beacon = new;
2049
2050 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2051 }
2052
2053 EXIT();
2054 return status;
2055}
2056
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002057#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2058
2059#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002060static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2061 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002062#else
2063static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2064 struct net_device *dev)
2065#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002066{
2067 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002068 hdd_context_t *pHddCtx = NULL;
2069 hdd_scaninfo_t *pScanInfo = NULL;
2070 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 VOS_STATUS status = 0;
2072
2073 ENTER();
2074
2075 if (NULL == pAdapter)
2076 {
2077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002078 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002079 return -ENODEV;
2080 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002081
Jeff Johnson4416a782013-03-25 14:17:50 -07002082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002083 if (NULL == pHddCtx)
2084 {
2085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002086 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002087 return -ENODEV;
2088 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002089 if (pHddCtx->isLogpInProgress)
2090 {
2091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2092 "%s:LOGP in Progress. Ignore!!!", __func__);
2093 return -EAGAIN;
2094 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002095
2096 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2097 if (NULL == staAdapter)
2098 {
2099 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2100 if (NULL == staAdapter)
2101 {
2102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002103 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002104 return -ENODEV;
2105 }
2106 }
2107
2108 pScanInfo = &pHddCtx->scan_info;
2109
Jeff Johnson4416a782013-03-25 14:17:50 -07002110 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002111 {
2112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2113 return -EAGAIN;
2114 }
2115
2116 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2117
2118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2119 __func__,pAdapter->device_mode);
2120
Jeff Johnsone7245742012-09-05 17:12:55 -07002121 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2122 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002123 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002124 hdd_abort_mac_scan(staAdapter->pHddCtx);
2125 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002126 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002127 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2128 if (!status)
2129 {
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002131 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002132 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002133 VOS_ASSERT(pScanInfo->mScanPending);
2134 return 0;
2135 }
2136 }
2137
Jeff Johnson295189b2012-06-20 16:38:30 -07002138 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 )
2141 {
2142 beacon_data_t *old;
2143
2144 old = pAdapter->sessionCtx.ap.beacon;
2145
2146 if (!old)
2147 return -ENOENT;
2148
Jeff Johnson295189b2012-06-20 16:38:30 -07002149 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002150
2151 mutex_lock(&pHddCtx->sap_lock);
2152 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2153 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002154 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 {
2156 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2157
2158 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2159
2160 if (!VOS_IS_STATUS_SUCCESS(status))
2161 {
2162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2163 ("ERROR: HDD vos wait for single_event failed!!\n"));
2164 VOS_ASSERT(0);
2165 }
2166 }
2167 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2168 }
2169 mutex_unlock(&pHddCtx->sap_lock);
2170
2171 if(status != VOS_STATUS_SUCCESS)
2172 {
2173 hddLog(VOS_TRACE_LEVEL_FATAL,
2174 "%s:Error!!! Stopping the BSS\n",__func__);
2175 return -EINVAL;
2176 }
2177
Jeff Johnson4416a782013-03-25 14:17:50 -07002178 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2180 ==eHAL_STATUS_FAILURE)
2181 {
2182 hddLog(LOGE,
2183 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2184 }
2185
Jeff Johnson4416a782013-03-25 14:17:50 -07002186 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2188 eANI_BOOLEAN_FALSE) )
2189 {
2190 hddLog(LOGE,
2191 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2192 }
2193
2194 // Reset WNI_CFG_PROBE_RSP Flags
2195 wlan_hdd_reset_prob_rspies(pAdapter);
2196
2197 pAdapter->sessionCtx.ap.beacon = NULL;
2198 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002199#ifdef WLAN_FEATURE_P2P_DEBUG
2200 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2201 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2202 {
2203 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2204 "GO got removed");
2205 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2206 }
2207#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002208 }
2209 EXIT();
2210 return status;
2211}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002212
2213#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2214
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302215static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2216 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002217 struct cfg80211_ap_settings *params)
2218{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302219 hdd_adapter_t *pAdapter;
2220 hdd_context_t *pHddCtx;
2221 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002222
2223 ENTER();
2224
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302225 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002226 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2228 "%s: Device is Null", __func__);
2229 return -ENODEV;
2230 }
2231
2232 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2233 if (NULL == pAdapter)
2234 {
2235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2236 "%s: HDD adapter is Null", __func__);
2237 return -ENODEV;
2238 }
2239
2240 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2241 {
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2243 "%s: HDD adapter magic is invalid", __func__);
2244 return -ENODEV;
2245 }
2246
2247 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2248 if (NULL == pHddCtx)
2249 {
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2251 "%s: HDD context is Null", __func__);
2252 return -ENODEV;
2253 }
2254
2255 if (pHddCtx->isLogpInProgress)
2256 {
2257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2258 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002259 return -EAGAIN;
2260 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302261
2262 if (pHddCtx->isLoadUnloadInProgress)
2263 {
2264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2265 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2266 return -EAGAIN;
2267 }
2268
2269 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2270 __func__, pAdapter->device_mode);
2271
2272 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002273 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002274 )
2275 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302276 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002277
2278 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302279
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002280 if (old)
2281 return -EALREADY;
2282
2283 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2284
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302285 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002286 {
2287 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302288 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002289 return -EINVAL;
2290 }
2291 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2293 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2294#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002295 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2296 params->ssid_len, params->hidden_ssid);
2297 }
2298
2299 EXIT();
2300 return status;
2301}
2302
2303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302304static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002305 struct net_device *dev,
2306 struct cfg80211_beacon_data *params)
2307{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302308 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002309 int status=VOS_STATUS_SUCCESS;
2310
2311 ENTER();
2312
2313 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2314 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002315 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2316 {
2317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2318 return -EAGAIN;
2319 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002320
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302321 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002322 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302323 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002324 {
2325 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302326
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302328
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002329 if (!old)
2330 return -ENOENT;
2331
2332 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2333
2334 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302335 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002336 "%s: Error!!! Allocating the new beacon\n",__func__);
2337 return -EINVAL;
2338 }
2339
2340 pAdapter->sessionCtx.ap.beacon = new;
2341
2342 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2343 }
2344
2345 EXIT();
2346 return status;
2347}
2348
2349#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2350
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
2352static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2353 struct net_device *dev,
2354 struct bss_parameters *params)
2355{
2356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2357
2358 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302359
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2361 __func__,pAdapter->device_mode);
2362
2363 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302365 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 {
2367 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2368 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302369 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002370 {
2371 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302372 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002373 }
2374
2375 EXIT();
2376 return 0;
2377}
2378
2379/*
2380 * FUNCTION: wlan_hdd_cfg80211_change_iface
2381 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2382 */
2383int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2384 struct net_device *ndev,
2385 enum nl80211_iftype type,
2386 u32 *flags,
2387 struct vif_params *params
2388 )
2389{
2390 struct wireless_dev *wdev;
2391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2392 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002393 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002394 tCsrRoamProfile *pRoamProfile = NULL;
2395 eCsrRoamBssType LastBSSType;
2396 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2397 eMib_dot11DesiredBssType connectedBssType;
2398 VOS_STATUS status;
2399
2400 ENTER();
2401
2402 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2403 {
2404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2405 return -EAGAIN;
2406 }
2407
2408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2409 __func__, pAdapter->device_mode);
2410
2411 wdev = ndev->ieee80211_ptr;
2412
2413#ifdef WLAN_BTAMP_FEATURE
2414 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2415 (NL80211_IFTYPE_ADHOC == type)||
2416 (NL80211_IFTYPE_AP == type)||
2417 (NL80211_IFTYPE_P2P_GO == type))
2418 {
2419 pHddCtx->isAmpAllowed = VOS_FALSE;
2420 // stop AMP traffic
2421 status = WLANBAP_StopAmp();
2422 if(VOS_STATUS_SUCCESS != status )
2423 {
2424 pHddCtx->isAmpAllowed = VOS_TRUE;
2425 hddLog(VOS_TRACE_LEVEL_FATAL,
2426 "%s: Failed to stop AMP", __func__);
2427 return -EINVAL;
2428 }
2429 }
2430#endif //WLAN_BTAMP_FEATURE
2431 /* Reset the current device mode bit mask*/
2432 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2433
2434 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002436 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 )
2438 {
2439 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2440 pRoamProfile = &pWextState->roamProfile;
2441 LastBSSType = pRoamProfile->BSSType;
2442
2443 switch (type)
2444 {
2445 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 hddLog(VOS_TRACE_LEVEL_INFO,
2448 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2449 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002450#ifdef WLAN_FEATURE_11AC
2451 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2452 {
2453 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2454 }
2455#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302456 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002457 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002458 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002459 //Check for sub-string p2p to confirm its a p2p interface
2460 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302461 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002462 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2463 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2464 }
2465 else
2466 {
2467 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002470 break;
2471 case NL80211_IFTYPE_ADHOC:
2472 hddLog(VOS_TRACE_LEVEL_INFO,
2473 "%s: setting interface Type to ADHOC", __func__);
2474 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2475 pRoamProfile->phyMode =
2476 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002477 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002478 wdev->iftype = type;
2479 break;
2480
2481 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002483 {
2484 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2485 "%s: setting interface Type to %s", __func__,
2486 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2487
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002488 //Cancel any remain on channel for GO mode
2489 if (NL80211_IFTYPE_P2P_GO == type)
2490 {
2491 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2492 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002493 if (NL80211_IFTYPE_AP == type)
2494 {
2495 /* As Loading WLAN Driver one interface being created for p2p device
2496 * address. This will take one HW STA and the max number of clients
2497 * that can connect to softAP will be reduced by one. so while changing
2498 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2499 * interface as it is not required in SoftAP mode.
2500 */
2501
2502 // Get P2P Adapter
2503 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2504
2505 if (pP2pAdapter)
2506 {
2507 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2508 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2509 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2510 }
2511 }
2512
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 //De-init the adapter.
2514 hdd_stop_adapter( pHddCtx, pAdapter );
2515 hdd_deinit_adapter( pHddCtx, pAdapter );
2516 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2518 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002519
2520 //Disable BMPS and IMPS if enabled
2521 //before starting Go
2522 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302524 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002525 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2526 {
2527 //Fail to Exit BMPS
2528 VOS_ASSERT(0);
2529 }
2530 }
2531
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002532 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2533 (pConfig->apRandomBssidEnabled))
2534 {
2535 /* To meet Android requirements create a randomized
2536 MAC address of the form 02:1A:11:Fx:xx:xx */
2537 get_random_bytes(&ndev->dev_addr[3], 3);
2538 ndev->dev_addr[0] = 0x02;
2539 ndev->dev_addr[1] = 0x1A;
2540 ndev->dev_addr[2] = 0x11;
2541 ndev->dev_addr[3] |= 0xF0;
2542 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2543 VOS_MAC_ADDR_SIZE);
2544 pr_info("wlan: Generated HotSpot BSSID "
2545 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2546 ndev->dev_addr[0],
2547 ndev->dev_addr[1],
2548 ndev->dev_addr[2],
2549 ndev->dev_addr[3],
2550 ndev->dev_addr[4],
2551 ndev->dev_addr[5]);
2552 }
2553
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 hdd_set_ap_ops( pAdapter->dev );
2555
2556 status = hdd_init_ap_mode(pAdapter);
2557 if(status != VOS_STATUS_SUCCESS)
2558 {
2559 hddLog(VOS_TRACE_LEVEL_FATAL,
2560 "%s: Error initializing the ap mode", __func__);
2561 return -EINVAL;
2562 }
2563 hdd_set_conparam(1);
2564
Jeff Johnson295189b2012-06-20 16:38:30 -07002565 /*interface type changed update in wiphy structure*/
2566 if(wdev)
2567 {
2568 wdev->iftype = type;
2569 pHddCtx->change_iface = type;
2570 }
2571 else
2572 {
2573 hddLog(VOS_TRACE_LEVEL_ERROR,
2574 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2575 return -EINVAL;
2576 }
2577 goto done;
2578 }
2579
2580 default:
2581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2582 __func__);
2583 return -EOPNOTSUPP;
2584 }
2585 }
2586 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 )
2589 {
2590 switch(type)
2591 {
2592 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002594 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002595 hdd_stop_adapter( pHddCtx, pAdapter );
2596 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002598 //Check for sub-string p2p to confirm its a p2p interface
2599 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002600 {
2601 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2602 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2603 }
2604 else
2605 {
2606 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002608 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002609 hdd_set_conparam(0);
2610 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2612 hdd_set_station_ops( pAdapter->dev );
2613 status = hdd_init_station_mode( pAdapter );
2614 if( VOS_STATUS_SUCCESS != status )
2615 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002616 /* In case of JB, for P2P-GO, only change interface will be called,
2617 * This is the right place to enable back bmps_imps()
2618 */
2619 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002620 goto done;
2621 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002623 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2625 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002626 goto done;
2627 default:
2628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2629 __func__);
2630 return -EOPNOTSUPP;
2631
2632 }
2633
2634 }
2635 else
2636 {
2637 return -EOPNOTSUPP;
2638 }
2639
2640
2641 if(pRoamProfile)
2642 {
2643 if ( LastBSSType != pRoamProfile->BSSType )
2644 {
2645 /*interface type changed update in wiphy structure*/
2646 wdev->iftype = type;
2647
2648 /*the BSS mode changed, We need to issue disconnect
2649 if connected or in IBSS disconnect state*/
2650 if ( hdd_connGetConnectedBssType(
2651 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2652 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2653 {
2654 /*need to issue a disconnect to CSR.*/
2655 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2656 if( eHAL_STATUS_SUCCESS ==
2657 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2658 pAdapter->sessionId,
2659 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2660 {
2661 wait_for_completion_interruptible_timeout(
2662 &pAdapter->disconnect_comp_var,
2663 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2664 }
2665 }
2666 }
2667 }
2668
2669done:
2670 /*set bitmask based on updated value*/
2671 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2672#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302673 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2675 {
2676 //we are ok to do AMP
2677 pHddCtx->isAmpAllowed = VOS_TRUE;
2678 }
2679#endif //WLAN_BTAMP_FEATURE
2680 EXIT();
2681 return 0;
2682}
2683
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002684#ifdef FEATURE_WLAN_TDLS
2685static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2686 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2687{
2688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2690 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002691 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002692
2693 ENTER();
2694
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302695 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002696 {
2697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2698 "Invalid arguments");
2699 return -EINVAL;
2700 }
Hoonki Lee27511902013-03-14 18:19:06 -07002701
2702 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2703 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2706 "%s: TDLS mode is disabled OR not enabled in FW."
2707 MAC_ADDRESS_STR " Request declined.",
2708 __func__, MAC_ADDR_ARRAY(mac));
2709 return -ENOTSUPP;
2710 }
2711
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002712 if (pHddCtx->isLogpInProgress)
2713 {
2714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2715 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002716 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002717 return -EBUSY;
2718 }
2719
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002720 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2721
2722 if ( NULL == pTdlsPeer ) {
2723 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2724 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2725 __func__, MAC_ADDR_ARRAY(mac), update);
2726 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002727 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002728
2729 /* in add station, we accept existing valid staId if there is */
2730 if ((0 == update) &&
2731 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2732 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002733 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002734 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002735 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002736 " link_status %d. staId %d. add station ignored.",
2737 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2738 return 0;
2739 }
2740 /* in change station, we accept only when staId is valid */
2741 if ((1 == update) &&
2742 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2743 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2744 {
2745 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2746 "%s: " MAC_ADDRESS_STR
2747 " link status %d. staId %d. change station %s.",
2748 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2749 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2750 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002751 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002752
2753 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002754 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002755 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2757 "%s: " MAC_ADDRESS_STR
2758 " TDLS setup is ongoing. Request declined.",
2759 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002760 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002761 }
2762
2763 /* first to check if we reached to maximum supported TDLS peer.
2764 TODO: for now, return -EPERM looks working fine,
2765 but need to check if any other errno fit into this category.*/
2766 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2767 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2769 "%s: " MAC_ADDRESS_STR
2770 " TDLS Max peer already connected. Request declined.",
2771 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002772 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002773 }
2774 else
2775 {
2776 hddTdlsPeer_t *pTdlsPeer;
2777 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002778 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002779 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2782 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002783 return -EPERM;
2784 }
2785 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002786 if (0 == update)
2787 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002788
Jeff Johnsond75fe012013-04-06 10:53:06 -07002789 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302790 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002791 {
2792 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2793 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002794 if(StaParams->htcap_present)
2795 {
2796 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2797 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2798 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2799 "ht_capa->extended_capabilities: %0x",
2800 StaParams->HTCap.extendedHtCapInfo);
2801 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002802 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2803 "params->capability: %0x",StaParams->capability);
2804 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2805 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002806 if(StaParams->vhtcap_present)
2807 {
2808 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2809 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2810 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2811 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2812 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002813 {
2814 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002816 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2817 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2818 "[%d]: %x ", i, StaParams->supported_rates[i]);
2819 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002820 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302821 else if ((1 == update) && (NULL == StaParams))
2822 {
2823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s : update is true, but staParams is NULL. Error!", __func__);
2825 return -EPERM;
2826 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002827
2828 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2829
2830 if (!update)
2831 {
2832 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2833 pAdapter->sessionId, mac);
2834 }
2835 else
2836 {
2837 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2838 pAdapter->sessionId, mac, StaParams);
2839 }
2840
2841 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2842 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2843
2844 if (!status)
2845 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002847 "%s: timeout waiting for tdls add station indication",
2848 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002849 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002850 }
2851 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2852 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002854 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002855 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002856 }
2857
2858 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002859
2860error:
2861 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2862 return -EPERM;
2863
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002864}
2865#endif
2866
Jeff Johnson295189b2012-06-20 16:38:30 -07002867static int wlan_hdd_change_station(struct wiphy *wiphy,
2868 struct net_device *dev,
2869 u8 *mac,
2870 struct station_parameters *params)
2871{
2872 VOS_STATUS status = VOS_STATUS_SUCCESS;
2873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302874 hdd_context_t *pHddCtx;
2875 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002876 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002877#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002878 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002879 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002880#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002881 ENTER();
2882
Gopichand Nakkala29149562013-05-10 21:43:41 +05302883 if ((NULL == pAdapter))
2884 {
2885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2886 "invalid adapter ");
2887 return -EINVAL;
2888 }
2889
2890 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2891 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2892
2893 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2894 {
2895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2896 "invalid HDD state or HDD station context");
2897 return -EINVAL;
2898 }
2899
2900 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002901 {
2902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2903 "%s:LOGP in Progress. Ignore!!!", __func__);
2904 return -EAGAIN;
2905 }
2906
Jeff Johnson295189b2012-06-20 16:38:30 -07002907 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2908
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002909 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2910 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002912 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302914 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002915 WLANTL_STA_AUTHENTICATED);
2916
Gopichand Nakkala29149562013-05-10 21:43:41 +05302917 if (status != VOS_STATUS_SUCCESS)
2918 {
2919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2920 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2921 return -EINVAL;
2922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002923 }
2924 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002925 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2926 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302927#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002928 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2929 StaParams.capability = params->capability;
2930 StaParams.uapsd_queues = params->uapsd_queues;
2931 StaParams.max_sp = params->max_sp;
2932
2933 if (0 != params->ext_capab_len)
2934 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2935 sizeof(StaParams.extn_capability));
2936
2937 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002938 {
2939 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002940 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002941 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002942
2943 StaParams.supported_rates_len = params->supported_rates_len;
2944
2945 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2946 * The supported_rates array , for all the structures propogating till Add Sta
2947 * to the firmware has to be modified , if the supplicant (ieee80211) is
2948 * modified to send more rates.
2949 */
2950
2951 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2952 */
2953 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2954 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2955
2956 if (0 != StaParams.supported_rates_len) {
2957 int i = 0;
2958 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2959 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002961 "Supported Rates with Length %d", StaParams.supported_rates_len);
2962 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002964 "[%d]: %0x", i, StaParams.supported_rates[i]);
2965 }
2966
2967 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002968 {
2969 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002970 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002971 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002972
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002973 if (0 != params->ext_capab_len ) {
2974 /*Define A Macro : TODO Sunil*/
2975 if ((1<<4) & StaParams.extn_capability[3]) {
2976 isBufSta = 1;
2977 }
2978 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002979 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
2980 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002981 //if (VOS_STATUS_SUCCESS != status) {
2982 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2983 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
2984 // return -EINVAL;
2985 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002986 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
2987
2988 if (VOS_STATUS_SUCCESS != status) {
2989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2990 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
2991 return -EINVAL;
2992 }
2993 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002994#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05302995 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2996 {
2997 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
2998 WLANTL_STA_AUTHENTICATED);
2999 if (status != VOS_STATUS_SUCCESS)
3000 {
3001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3002 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3003 return -EINVAL;
3004 }
3005 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3007 "%s: TL Moving to Authenticated state", __func__);
3008 }
3009 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303010
Jeff Johnsone7245742012-09-05 17:12:55 -07003011 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003012 return status;
3013}
3014
3015/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003016 * FUNCTION: wlan_hdd_cfg80211_add_key
3017 * This function is used to initialize the key information
3018 */
3019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003020static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003021 struct net_device *ndev,
3022 u8 key_index, bool pairwise,
3023 const u8 *mac_addr,
3024 struct key_params *params
3025 )
3026#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003027static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003028 struct net_device *ndev,
3029 u8 key_index, const u8 *mac_addr,
3030 struct key_params *params
3031 )
3032#endif
3033{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003035 tCsrRoamSetKey setKey;
3036 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3037 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003038 v_U32_t roamId= 0xFF;
3039 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003040 hdd_hostapd_state_t *pHostapdState;
3041 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003042 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003043
3044 ENTER();
3045
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003046 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3047 {
3048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s:LOGP in Progress. Ignore!!!", __func__);
3050 return -EAGAIN;
3051 }
3052
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3054 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003055
3056 if (CSR_MAX_NUM_KEY <= key_index)
3057 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 key_index);
3060
3061 return -EINVAL;
3062 }
3063
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003064 if (CSR_MAX_KEY_LEN < params->key_len)
3065 {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3067 params->key_len);
3068
3069 return -EINVAL;
3070 }
3071
3072 hddLog(VOS_TRACE_LEVEL_INFO,
3073 "%s: called with key index = %d & key length %d",
3074 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003075
3076 /*extract key idx, key len and key*/
3077 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3078 setKey.keyId = key_index;
3079 setKey.keyLength = params->key_len;
3080 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3081
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003082 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003083 {
3084 case WLAN_CIPHER_SUITE_WEP40:
3085 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3086 break;
3087
3088 case WLAN_CIPHER_SUITE_WEP104:
3089 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3090 break;
3091
3092 case WLAN_CIPHER_SUITE_TKIP:
3093 {
3094 u8 *pKey = &setKey.Key[0];
3095 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3096
3097 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3098
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003099 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003100
3101 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 |--------------|----------|----------|
3104 <---16bytes---><--8bytes--><--8bytes-->
3105
3106 */
3107 /*Sme expects the 32 bytes key to be in the below order
3108
3109 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003110 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003111 |--------------|----------|----------|
3112 <---16bytes---><--8bytes--><--8bytes-->
3113 */
3114 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003115 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003116
3117 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003118 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003121 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003122
3123
3124 break;
3125 }
3126
3127 case WLAN_CIPHER_SUITE_CCMP:
3128 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3129 break;
3130
3131#ifdef FEATURE_WLAN_WAPI
3132 case WLAN_CIPHER_SUITE_SMS4:
3133 {
3134 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3135 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3136 params->key, params->key_len);
3137 return 0;
3138 }
3139#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003140
Jeff Johnson295189b2012-06-20 16:38:30 -07003141#ifdef FEATURE_WLAN_CCX
3142 case WLAN_CIPHER_SUITE_KRK:
3143 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3144 break;
3145#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003146
3147#ifdef WLAN_FEATURE_11W
3148 case WLAN_CIPHER_SUITE_AES_CMAC:
3149 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003150 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003151#endif
3152
Jeff Johnson295189b2012-06-20 16:38:30 -07003153 default:
3154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3155 __func__, params->cipher);
3156 return -EOPNOTSUPP;
3157 }
3158
3159 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3160 __func__, setKey.encType);
3161
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003162 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3164 (!pairwise)
3165#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003167#endif
3168 )
3169 {
3170 /* set group key*/
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003172 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003173 __func__, __LINE__);
3174 setKey.keyDirection = eSIR_RX_ONLY;
3175 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3176 }
3177 else
3178 {
3179 /* set pairwise key*/
3180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3181 "%s- %d: setting pairwise key",
3182 __func__, __LINE__);
3183 setKey.keyDirection = eSIR_TX_RX;
3184 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3185 }
3186
Gopichand Nakkala29149562013-05-10 21:43:41 +05303187 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3188 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3189 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003190 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003191 if( pHostapdState->bssState == BSS_START )
3192 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003193 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3194
3195 if ( status != eHAL_STATUS_SUCCESS )
3196 {
3197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3198 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3199 __LINE__, status );
3200 }
3201 }
3202
3203 /* Saving WEP keys */
3204 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3205 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3206 {
3207 //Save the wep key in ap context. Issue setkey after the BSS is started.
3208 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3209 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3210 }
3211 else
3212 {
3213 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003214 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003215 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3216 }
3217 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003218 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3219 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003220 {
3221 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3222 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3223
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3225 if (!pairwise)
3226#else
3227 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3228#endif
3229 {
3230 /* set group key*/
3231 if (pHddStaCtx->roam_info.deferKeyComplete)
3232 {
3233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3234 "%s- %d: Perform Set key Complete",
3235 __func__, __LINE__);
3236 hdd_PerformRoamSetKeyComplete(pAdapter);
3237 }
3238 }
3239
Jeff Johnson295189b2012-06-20 16:38:30 -07003240 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3241
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003242 pWextState->roamProfile.Keys.defaultIndex = key_index;
3243
3244
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003245 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 params->key, params->key_len);
3247
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303248
Jeff Johnson295189b2012-06-20 16:38:30 -07003249 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3250
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303251 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003252 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303253 __func__, setKey.peerMac[0], setKey.peerMac[1],
3254 setKey.peerMac[2], setKey.peerMac[3],
3255 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003256 setKey.keyDirection);
3257
3258 vos_status = wlan_hdd_check_ula_done(pAdapter);
3259
3260 if ( vos_status != VOS_STATUS_SUCCESS )
3261 {
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3264 __LINE__, vos_status );
3265
3266 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3267
3268 return -EINVAL;
3269
3270 }
3271
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003272#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303273 /* The supplicant may attempt to set the PTK once pre-authentication
3274 is done. Save the key in the UMAC and include it in the ADD BSS
3275 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003276 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303277 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003278 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303279 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3280 "%s: Update PreAuth Key success", __func__);
3281 return 0;
3282 }
3283 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3284 {
3285 hddLog(VOS_TRACE_LEVEL_ERROR,
3286 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303287 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003288 }
3289#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003290
3291 /* issue set key request to SME*/
3292 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3293 pAdapter->sessionId, &setKey, &roamId );
3294
3295 if ( 0 != status )
3296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303297 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003298 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3299 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3300 return -EINVAL;
3301 }
3302
3303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303304 /* in case of IBSS as there was no information available about WEP keys during
3305 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303307 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3308 !( ( IW_AUTH_KEY_MGMT_802_1X
3309 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003310 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3311 )
3312 &&
3313 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3314 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3315 )
3316 )
3317 {
3318 setKey.keyDirection = eSIR_RX_ONLY;
3319 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3320
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303321 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303323 __func__, setKey.peerMac[0], setKey.peerMac[1],
3324 setKey.peerMac[2], setKey.peerMac[3],
3325 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003326 setKey.keyDirection);
3327
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303328 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003329 pAdapter->sessionId, &setKey, &roamId );
3330
3331 if ( 0 != status )
3332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303333 hddLog(VOS_TRACE_LEVEL_ERROR,
3334 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003335 __func__, status);
3336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3337 return -EINVAL;
3338 }
3339 }
3340 }
3341
3342 return 0;
3343}
3344
3345/*
3346 * FUNCTION: wlan_hdd_cfg80211_get_key
3347 * This function is used to get the key information
3348 */
3349#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303350static int wlan_hdd_cfg80211_get_key(
3351 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003352 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303353 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003354 const u8 *mac_addr, void *cookie,
3355 void (*callback)(void *cookie, struct key_params*)
3356 )
3357#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303358static int wlan_hdd_cfg80211_get_key(
3359 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003360 struct net_device *ndev,
3361 u8 key_index, const u8 *mac_addr, void *cookie,
3362 void (*callback)(void *cookie, struct key_params*)
3363 )
3364#endif
3365{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303366 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003367 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3368 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3369 struct key_params params;
3370
3371 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303372
Jeff Johnson295189b2012-06-20 16:38:30 -07003373 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3374 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303375
Jeff Johnson295189b2012-06-20 16:38:30 -07003376 memset(&params, 0, sizeof(params));
3377
3378 if (CSR_MAX_NUM_KEY <= key_index)
3379 {
3380 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003382
3383 switch(pRoamProfile->EncryptionType.encryptionType[0])
3384 {
3385 case eCSR_ENCRYPT_TYPE_NONE:
3386 params.cipher = IW_AUTH_CIPHER_NONE;
3387 break;
3388
3389 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3390 case eCSR_ENCRYPT_TYPE_WEP40:
3391 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3392 break;
3393
3394 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3395 case eCSR_ENCRYPT_TYPE_WEP104:
3396 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3397 break;
3398
3399 case eCSR_ENCRYPT_TYPE_TKIP:
3400 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3401 break;
3402
3403 case eCSR_ENCRYPT_TYPE_AES:
3404 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3405 break;
3406
3407 default:
3408 params.cipher = IW_AUTH_CIPHER_NONE;
3409 break;
3410 }
3411
3412 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3413 params.seq_len = 0;
3414 params.seq = NULL;
3415 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3416 callback(cookie, &params);
3417 return 0;
3418}
3419
3420/*
3421 * FUNCTION: wlan_hdd_cfg80211_del_key
3422 * This function is used to delete the key information
3423 */
3424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303425static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003426 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303427 u8 key_index,
3428 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003429 const u8 *mac_addr
3430 )
3431#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303432static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003433 struct net_device *ndev,
3434 u8 key_index,
3435 const u8 *mac_addr
3436 )
3437#endif
3438{
3439 int status = 0;
3440
3441 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303442 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003443 //it is observed that this is invalidating peer
3444 //key index whenever re-key is done. This is affecting data link.
3445 //It should be ok to ignore del_key.
3446#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3448 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3450 tCsrRoamSetKey setKey;
3451 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303452
Jeff Johnson295189b2012-06-20 16:38:30 -07003453 ENTER();
3454
3455 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3456 __func__,pAdapter->device_mode);
3457
3458 if (CSR_MAX_NUM_KEY <= key_index)
3459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003461 key_index);
3462
3463 return -EINVAL;
3464 }
3465
3466 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3467 setKey.keyId = key_index;
3468
3469 if (mac_addr)
3470 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3471 else
3472 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3473
3474 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3475
3476 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003477 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303478 )
3479 {
3480
3481 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003482 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3483 if( pHostapdState->bssState == BSS_START)
3484 {
3485 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303486
Jeff Johnson295189b2012-06-20 16:38:30 -07003487 if ( status != eHAL_STATUS_SUCCESS )
3488 {
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3491 __LINE__, status );
3492 }
3493 }
3494 }
3495 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303496 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003497 )
3498 {
3499 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3500
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303501 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3502
3503 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303505 __func__, setKey.peerMac[0], setKey.peerMac[1],
3506 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003507 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303508 if(pAdapter->sessionCtx.station.conn_info.connState ==
3509 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303511 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003512 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303513
Jeff Johnson295189b2012-06-20 16:38:30 -07003514 if ( 0 != status )
3515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 "%s: sme_RoamSetKey failure, returned %d",
3518 __func__, status);
3519 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3520 return -EINVAL;
3521 }
3522 }
3523 }
3524#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003525 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 return status;
3527}
3528
3529/*
3530 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3531 * This function is used to set the default tx key index
3532 */
3533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3534static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3535 struct net_device *ndev,
3536 u8 key_index,
3537 bool unicast, bool multicast)
3538#else
3539static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3540 struct net_device *ndev,
3541 u8 key_index)
3542#endif
3543{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003545 int status = 0;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303546 hdd_wext_state_t *pWextState;
3547 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003548
3549 ENTER();
3550
Gopichand Nakkala29149562013-05-10 21:43:41 +05303551 if ((NULL == pAdapter))
3552 {
3553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3554 "invalid adapter");
3555 return -EINVAL;
3556 }
3557
3558 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3559 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3560
3561 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3562 {
3563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3564 "invalid Wext state or HDD context");
3565 return -EINVAL;
3566 }
3567
Jeff Johnson295189b2012-06-20 16:38:30 -07003568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3569 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303570
Jeff Johnson295189b2012-06-20 16:38:30 -07003571 if (CSR_MAX_NUM_KEY <= key_index)
3572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003574 key_index);
3575
3576 return -EINVAL;
3577 }
3578
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003579 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3580 {
3581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3582 "%s:LOGP in Progress. Ignore!!!", __func__);
3583 return -EAGAIN;
3584 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303585
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303588 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303590 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003591 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303592 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003593 pWextState->roamProfile.EncryptionType.encryptionType[0])
3594 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595 {
3596 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 tCsrRoamSetKey setKey;
3600 v_U32_t roamId= 0xFF;
3601 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303602
3603 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303605
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 Keys->defaultIndex = (u8)key_index;
3607 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3608 setKey.keyId = key_index;
3609 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303610
3611 vos_mem_copy(&setKey.Key[0],
3612 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303614
Gopichand Nakkala29149562013-05-10 21:43:41 +05303615 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303616
3617 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003618 &pHddStaCtx->conn_info.bssId[0],
3619 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303620
Gopichand Nakkala29149562013-05-10 21:43:41 +05303621 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3622 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3623 eCSR_ENCRYPT_TYPE_WEP104)
3624 {
3625 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3626 even though ap is configured for WEP-40 encryption. In this canse the key length
3627 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3628 type(104) and switching encryption type to 40*/
3629 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3630 eCSR_ENCRYPT_TYPE_WEP40;
3631 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3632 eCSR_ENCRYPT_TYPE_WEP40;
3633 }
3634
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303635 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303637
Jeff Johnson295189b2012-06-20 16:38:30 -07003638 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303639 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003640 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303641
Jeff Johnson295189b2012-06-20 16:38:30 -07003642 if ( 0 != status )
3643 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303644 hddLog(VOS_TRACE_LEVEL_ERROR,
3645 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 status);
3647 return -EINVAL;
3648 }
3649 }
3650 }
3651
3652 /* In SoftAp mode setting key direction for default mode */
3653 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3654 {
3655 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3656 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3657 (eCSR_ENCRYPT_TYPE_AES !=
3658 pWextState->roamProfile.EncryptionType.encryptionType[0])
3659 )
3660 {
3661 /* Saving key direction for default key index to TX default */
3662 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3663 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3664 }
3665 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303666
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 return status;
3668}
3669
Jeff Johnson295189b2012-06-20 16:38:30 -07003670/*
3671 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3672 * This function is used to inform the BSS details to nl80211 interface.
3673 */
3674static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3675 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3676{
3677 struct net_device *dev = pAdapter->dev;
3678 struct wireless_dev *wdev = dev->ieee80211_ptr;
3679 struct wiphy *wiphy = wdev->wiphy;
3680 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3681 int chan_no;
3682 int ie_length;
3683 const char *ie;
3684 unsigned int freq;
3685 struct ieee80211_channel *chan;
3686 int rssi = 0;
3687 struct cfg80211_bss *bss = NULL;
3688
3689 ENTER();
3690
3691 if( NULL == pBssDesc )
3692 {
3693 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3694 return bss;
3695 }
3696
3697 chan_no = pBssDesc->channelId;
3698 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3699 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3700
3701 if( NULL == ie )
3702 {
3703 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3704 return bss;
3705 }
3706
3707#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3708 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3709 {
3710 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3711 }
3712 else
3713 {
3714 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3715 }
3716#else
3717 freq = ieee80211_channel_to_frequency(chan_no);
3718#endif
3719
3720 chan = __ieee80211_get_channel(wiphy, freq);
3721
3722 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3723 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3724 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3725 if (bss == NULL)
3726 {
3727 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3728
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303729 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3730 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 pBssDesc->capabilityInfo,
3732 pBssDesc->beaconInterval, ie, ie_length,
3733 rssi, GFP_KERNEL ));
3734}
3735 else
3736 {
3737 return bss;
3738 }
3739}
3740
3741
3742
3743/*
3744 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3745 * This function is used to inform the BSS details to nl80211 interface.
3746 */
3747struct cfg80211_bss*
3748wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3749 tSirBssDescription *bss_desc
3750 )
3751{
3752 /*
3753 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3754 already exists in bss data base of cfg80211 for that particular BSS ID.
3755 Using cfg80211_inform_bss_frame to update the bss entry instead of
3756 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3757 now there is no possibility to get the mgmt(probe response) frame from PE,
3758 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3759 cfg80211_inform_bss_frame.
3760 */
3761 struct net_device *dev = pAdapter->dev;
3762 struct wireless_dev *wdev = dev->ieee80211_ptr;
3763 struct wiphy *wiphy = wdev->wiphy;
3764 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003765#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3766 qcom_ie_age *qie_age = NULL;
3767 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3768#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003769 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003770#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003771 const char *ie =
3772 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3773 unsigned int freq;
3774 struct ieee80211_channel *chan;
3775 struct ieee80211_mgmt *mgmt =
3776 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3777 struct cfg80211_bss *bss_status = NULL;
3778 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3779 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003780#ifdef WLAN_OPEN_SOURCE
3781 struct timespec ts;
3782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003783
3784 ENTER();
3785
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003786 if (!mgmt)
3787 return NULL;
3788
Jeff Johnson295189b2012-06-20 16:38:30 -07003789 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003790
3791#ifdef WLAN_OPEN_SOURCE
3792 /* Android does not want the timestamp from the frame.
3793 Instead it wants a monotonic increasing value */
3794 get_monotonic_boottime(&ts);
3795 mgmt->u.probe_resp.timestamp =
3796 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3797#else
3798 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3800 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003801
3802#endif
3803
Jeff Johnson295189b2012-06-20 16:38:30 -07003804 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3805 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003806
3807#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3808 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3809 /* Assuming this is the last IE, copy at the end */
3810 ie_length -=sizeof(qcom_ie_age);
3811 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3812 qie_age->element_id = QCOM_VENDOR_IE_ID;
3813 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3814 qie_age->oui_1 = QCOM_OUI1;
3815 qie_age->oui_2 = QCOM_OUI2;
3816 qie_age->oui_3 = QCOM_OUI3;
3817 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3818 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3819#endif
3820
Jeff Johnson295189b2012-06-20 16:38:30 -07003821 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3822
3823 mgmt->frame_control |=
3824 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3825
3826#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303827 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003828 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3829 {
3830 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3831 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303832 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003833 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3834
3835 {
3836 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3837 }
3838 else
3839 {
3840 kfree(mgmt);
3841 return NULL;
3842 }
3843#else
3844 freq = ieee80211_channel_to_frequency(chan_no);
3845#endif
3846 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003847 /*when the band is changed on the fly using the GUI, three things are done
3848 * 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)
3849 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3850 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3851 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3852 * and discards the channels correponding to previous band and calls back with zero bss results.
3853 * 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
3854 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3855 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3856 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3857 * So drop the bss and continue to next bss.
3858 */
3859 if(chan == NULL)
3860 {
3861 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003862 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003863 return NULL;
3864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003865 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303866 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003867 * */
3868 if (( eConnectionState_Associated ==
3869 pAdapter->sessionCtx.station.conn_info.connState ) &&
3870 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3871 pAdapter->sessionCtx.station.conn_info.bssId,
3872 WNI_CFG_BSSID_LEN)))
3873 {
3874 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3875 rssi = (pAdapter->rssi * 100);
3876 }
3877 else
3878 {
3879 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3880 }
3881
3882 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3883 frame_len, rssi, GFP_KERNEL);
3884 kfree(mgmt);
3885 return bss_status;
3886}
3887
3888/*
3889 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3890 * This function is used to update the BSS data base of CFG8011
3891 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303892struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 tCsrRoamInfo *pRoamInfo
3894 )
3895{
3896 tCsrRoamConnectedProfile roamProfile;
3897 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3898 struct cfg80211_bss *bss = NULL;
3899
3900 ENTER();
3901
3902 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3903 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3904
3905 if (NULL != roamProfile.pBssDesc)
3906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303907 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 &roamProfile);
3909
3910 if (NULL == bss)
3911 {
3912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3913 __func__);
3914 }
3915
3916 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3917 }
3918 else
3919 {
3920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3921 __func__);
3922 }
3923 return bss;
3924}
3925
3926/*
3927 * FUNCTION: wlan_hdd_cfg80211_update_bss
3928 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303929static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3930 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07003931 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932{
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3934 tCsrScanResultInfo *pScanResult;
3935 eHalStatus status = 0;
3936 tScanResultHandle pResult;
3937 struct cfg80211_bss *bss_status = NULL;
3938
3939 ENTER();
3940
3941 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3942 {
3943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
3944 return -EAGAIN;
3945 }
3946
3947 /*
3948 * start getting scan results and populate cgf80211 BSS database
3949 */
3950 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
3951
3952 /* no scan results */
3953 if (NULL == pResult)
3954 {
3955 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
3956 return status;
3957 }
3958
3959 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
3960
3961 while (pScanResult)
3962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303963 /*
3964 * cfg80211_inform_bss() is not updating ie field of bss entry, if
3965 * entry already exists in bss data base of cfg80211 for that
3966 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
3967 * bss entry instead of cfg80211_inform_bss, But this call expects
3968 * mgmt packet as input. As of now there is no possibility to get
3969 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07003970 * ieee80211_mgmt(probe response) and passing to c
3971 * fg80211_inform_bss_frame.
3972 * */
3973
3974 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
3975 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303976
Jeff Johnson295189b2012-06-20 16:38:30 -07003977
3978 if (NULL == bss_status)
3979 {
3980 hddLog(VOS_TRACE_LEVEL_INFO,
3981 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
3982 }
3983 else
3984 {
3985 cfg80211_put_bss(bss_status);
3986 }
3987
3988 pScanResult = sme_ScanResultGetNext(hHal, pResult);
3989 }
3990
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07003992
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303993 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003994}
3995
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003996void
3997hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
3998{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303999 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004000 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4001 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4002 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004003} /****** end hddPrintMacAddr() ******/
4004
4005void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004006hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004007{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304008 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004009 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4010 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4011 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4012 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004013} /****** end hddPrintPmkId() ******/
4014
4015//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4016//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4017
4018//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4019//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4020
4021#define dump_bssid(bssid) \
4022 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004023 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4024 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4025 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004026 }
4027
4028#define dump_pmkid(pMac, pmkid) \
4029 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004030 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4031 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4032 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004033 }
4034
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004035#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004036/*
4037 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4038 * This function is used to notify the supplicant of a new PMKSA candidate.
4039 */
4040int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004042 int index, bool preauth )
4043{
Jeff Johnsone7245742012-09-05 17:12:55 -07004044#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004045 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004046 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004047
4048 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004049 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004050
4051 if( NULL == pRoamInfo )
4052 {
4053 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4054 return -EINVAL;
4055 }
4056
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004057 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4058 {
4059 dump_bssid(pRoamInfo->bssid);
4060 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004061 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004062 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004063#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004065}
4066#endif //FEATURE_WLAN_LFR
4067
Jeff Johnson295189b2012-06-20 16:38:30 -07004068/*
4069 * FUNCTION: hdd_cfg80211_scan_done_callback
4070 * scanning callback function, called after finishing scan
4071 *
4072 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304073static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4075{
4076 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304077 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004078 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004079 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4080 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 struct cfg80211_scan_request *req = NULL;
4082 int ret = 0;
4083
4084 ENTER();
4085
4086 hddLog(VOS_TRACE_LEVEL_INFO,
4087 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304088 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004089 __func__, halHandle, pContext, (int) scanId, (int) status);
4090
4091 //Block on scan req completion variable. Can't wait forever though.
4092 ret = wait_for_completion_interruptible_timeout(
4093 &pScanInfo->scan_req_completion_event,
4094 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4095 if (!ret)
4096 {
4097 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004098 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004099 }
4100
4101 if(pScanInfo->mScanPending != VOS_TRUE)
4102 {
4103 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004104 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004105 }
4106
4107 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304108 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004109 {
4110 hddLog(VOS_TRACE_LEVEL_INFO,
4111 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304112 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004113 (int) scanId);
4114 }
4115
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304116 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 pAdapter);
4118
4119 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004121
4122
4123 /* If any client wait scan result through WEXT
4124 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004125 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 {
4127 /* The other scan request waiting for current scan finish
4128 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004129 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004131 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 }
4133 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004134 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004135 {
4136 struct net_device *dev = pAdapter->dev;
4137 union iwreq_data wrqu;
4138 int we_event;
4139 char *msg;
4140
4141 memset(&wrqu, '\0', sizeof(wrqu));
4142 we_event = SIOCGIWSCAN;
4143 msg = NULL;
4144 wireless_send_event(dev, we_event, &wrqu, msg);
4145 }
4146 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004147 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004148
4149 /* Get the Scan Req */
4150 req = pAdapter->request;
4151
4152 if (!req)
4153 {
4154 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004155 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004156 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 }
4158
4159 /*
4160 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304161 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004162 req->n_ssids = 0;
4163 req->n_channels = 0;
4164 req->ie = 0;
4165
Jeff Johnson295189b2012-06-20 16:38:30 -07004166 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004167 /* Scan is no longer pending */
4168 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004169
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004170 /*
4171 * cfg80211_scan_done informing NL80211 about completion
4172 * of scanning
4173 */
4174 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004175 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004176
Jeff Johnsone7245742012-09-05 17:12:55 -07004177allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004178 /* release the wake lock at the end of the scan*/
4179 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004180
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004181 /* Acquire wakelock to handle the case where APP's tries to suspend
4182 * immediatly after the driver gets connect request(i.e after scan)
4183 * from supplicant, this result in app's is suspending and not able
4184 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004185 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004186
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004187#ifdef FEATURE_WLAN_TDLS
4188 wlan_hdd_tdls_scan_done_callback(pAdapter);
4189#endif
4190
Jeff Johnson295189b2012-06-20 16:38:30 -07004191 EXIT();
4192 return 0;
4193}
4194
4195/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004196 * FUNCTION: hdd_isScanAllowed
4197 * Go through each adapter and check if scan allowed
4198 *
4199 */
4200v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4201{
4202 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4203 hdd_station_ctx_t *pHddStaCtx = NULL;
4204 hdd_adapter_t *pAdapter = NULL;
4205 VOS_STATUS status = 0;
4206 v_U8_t staId = 0;
4207 v_U8_t *staMac = NULL;
4208
4209 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4210
4211 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4212 {
4213 pAdapter = pAdapterNode->pAdapter;
4214
4215 if( pAdapter )
4216 {
4217 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304218 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004219 __func__, pAdapter->device_mode);
4220 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4221 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4222 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4223 {
4224 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4225 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4226 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4227 {
4228 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4229 hddLog(VOS_TRACE_LEVEL_ERROR,
4230 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304231 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004232 staMac[0], staMac[1], staMac[2],
4233 staMac[3], staMac[4], staMac[5]);
4234 return VOS_FALSE;
4235 }
4236 }
4237 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4238 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4239 {
4240 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4241 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304242 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004243 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4244 {
4245 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4246
4247 hddLog(VOS_TRACE_LEVEL_ERROR,
4248 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304249 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004250 staMac[0], staMac[1], staMac[2],
4251 staMac[3], staMac[4], staMac[5]);
4252 return VOS_FALSE;
4253 }
4254 }
4255 }
4256 }
4257 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4258 pAdapterNode = pNext;
4259 }
4260 hddLog(VOS_TRACE_LEVEL_INFO,
4261 "%s: Scan allowed", __func__);
4262 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304263}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004264
4265/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 * FUNCTION: wlan_hdd_cfg80211_scan
4267 * this scan respond to scan trigger and update cfg80211 scan database
4268 * later, scan dump command can be used to recieve scan results
4269 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004270int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4272 struct net_device *dev,
4273#endif
4274 struct cfg80211_scan_request *request)
4275{
4276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4277 struct net_device *dev = request->wdev->netdev;
4278#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004280 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4281 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4282 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4283 tCsrScanRequest scanRequest;
4284 tANI_U8 *channelList = NULL, i;
4285 v_U32_t scanId = 0;
4286 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004287 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004288 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004289
4290 ENTER();
4291
4292 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4293 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004294
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004295 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004296 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004297 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004298 {
4299 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004300 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4301 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004302 return -EBUSY;
4303 }
4304
Jeff Johnson295189b2012-06-20 16:38:30 -07004305#ifdef WLAN_BTAMP_FEATURE
4306 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004307 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004308 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004309 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004310 "%s: No scanning when AMP is on", __func__);
4311 return -EOPNOTSUPP;
4312 }
4313#endif
4314 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004315 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004317 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004318 "%s: Not scanning on device_mode = %d",
4319 __func__, pAdapter->device_mode);
4320 return -EOPNOTSUPP;
4321 }
4322
4323 if (TRUE == pScanInfo->mScanPending)
4324 {
4325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004326 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004327 }
4328
4329 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4330 {
4331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4332 "%s:LOGP in Progress. Ignore!!!", __func__);
4333 return -EAGAIN;
4334 }
4335
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004336 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4337 {
4338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4339 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4340 return -EAGAIN;
4341 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004343 //Channel and action frame is pending
4344 //Otherwise Cancel Remain On Channel and allow Scan
4345 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004346 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004347 {
4348 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4349 return -EBUSY;
4350 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004351#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004352 /* if tdls disagree scan right now, return immediately.
4353 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4354 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4355 */
4356 status = wlan_hdd_tdls_scan_callback (pAdapter,
4357 wiphy,
4358#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4359 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004360#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004361 request);
4362 if(status <= 0)
4363 {
4364 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4365 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004366 }
4367#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004368
Jeff Johnson295189b2012-06-20 16:38:30 -07004369 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4370 {
4371 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004372 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004375 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4376 {
4377 hddLog(VOS_TRACE_LEVEL_WARN,
4378 "%s: MAX TM Level Scan not allowed", __func__);
4379 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304380 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 }
4382 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4383
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004384 /* Check if scan is allowed at this point of time.
4385 */
4386 if (!hdd_isScanAllowed(pHddCtx))
4387 {
4388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4389 return -EBUSY;
4390 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304391
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4393
4394 if (NULL != request)
4395 {
4396 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304397 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004398
4399 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4400 * Becasue of this, driver is assuming that this is not wildcard scan and so
4401 * is not aging out the scan results.
4402 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004403 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004404 {
4405 request->n_ssids = 0;
4406 }
4407
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004408 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004409 {
4410 tCsrSSIDInfo *SsidInfo;
4411 int j;
4412 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4413 /* Allocate num_ssid tCsrSSIDInfo structure */
4414 SsidInfo = scanRequest.SSIDs.SSIDList =
4415 ( tCsrSSIDInfo *)vos_mem_malloc(
4416 request->n_ssids*sizeof(tCsrSSIDInfo));
4417
4418 if(NULL == scanRequest.SSIDs.SSIDList)
4419 {
4420 hddLog(VOS_TRACE_LEVEL_ERROR,
4421 "memory alloc failed SSIDInfo buffer");
4422 return -ENOMEM;
4423 }
4424
4425 /* copy all the ssid's and their length */
4426 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4427 {
4428 /* get the ssid length */
4429 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4430 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4431 SsidInfo->SSID.length);
4432 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4433 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4434 j, SsidInfo->SSID.ssId);
4435 }
4436 /* set the scan type to active */
4437 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4438 }
4439 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4440 {
4441 /* set the scan type to active */
4442 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4443 }
4444 else
4445 {
4446 /*Set the scan type to default type, in this case it is ACTIVE*/
4447 scanRequest.scanType = pScanInfo->scan_mode;
4448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304449 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4451 }
4452 else
4453 {
4454 /* set the scan type to active */
4455 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4456 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4457
4458 /* set min and max channel time to zero */
4459 scanRequest.minChnTime = 0;
4460 scanRequest.maxChnTime = 0;
4461 }
4462
4463 /* set BSSType to default type */
4464 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4465
4466 /*TODO: scan the requested channels only*/
4467
4468 /*Right now scanning all the channels */
4469 if( request )
4470 {
4471 if( request->n_channels )
4472 {
4473 channelList = vos_mem_malloc( request->n_channels );
4474 if( NULL == channelList )
4475 {
4476 status = -ENOMEM;
4477 goto free_mem;
4478 }
4479
4480 for( i = 0 ; i < request->n_channels ; i++ )
4481 channelList[i] = request->channels[i]->hw_value;
4482 }
4483
4484 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4485 scanRequest.ChannelInfo.ChannelList = channelList;
4486
4487 /* set requestType to full scan */
4488 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304489
4490 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004491 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304492 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004493 */
4494
4495 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304496 * and in that case driver shoudnt flush scan results. If
4497 * driver flushes the scan results here and unfortunately if
4498 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004499 * fails which is not desired
4500 */
4501
4502 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4503 {
4504 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4505 pAdapter->sessionId );
4506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004507
4508 if( request->ie_len )
4509 {
4510 /* save this for future association (join requires this) */
4511 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4512 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4513 pScanInfo->scanAddIE.length = request->ie_len;
4514
4515 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004516 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4517 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004518 )
4519 {
4520 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4521 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4522 }
4523
4524 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4525 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4526
Jeff Johnson295189b2012-06-20 16:38:30 -07004527 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4528 request->ie_len);
4529 if (pP2pIe != NULL)
4530 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004531#ifdef WLAN_FEATURE_P2P_DEBUG
4532 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4533 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4534 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4535 {
4536 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4537 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4538 "Go nego completed to Connection is started");
4539 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4540 "for 8way Handshake");
4541 }
4542 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4543 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4544 {
4545 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4546 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4547 "Disconnected state to Connection is started");
4548 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4549 "for 4way Handshake");
4550 }
4551#endif
4552
Jeff Johnsone7245742012-09-05 17:12:55 -07004553 /* no_cck will be set during p2p find to disable 11b rates */
4554 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 hddLog(VOS_TRACE_LEVEL_INFO,
4557 "%s: This is a P2P Search", __func__);
4558 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004559
Jeff Johnsone7245742012-09-05 17:12:55 -07004560 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4561 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004562 /* set requestType to P2P Discovery */
4563 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004564 }
4565
4566 /*
4567 Skip Dfs Channel in case of P2P Search
4568 if it is set in ini file
4569 */
4570 if(cfg_param->skipDfsChnlInP2pSearch)
4571 {
4572 scanRequest.skipDfsChnlInP2pSearch = 1;
4573 }
4574 else
4575 {
4576 scanRequest.skipDfsChnlInP2pSearch = 0;
4577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004578
Jeff Johnson295189b2012-06-20 16:38:30 -07004579 }
4580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004581 }
4582 }
4583
4584 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4585
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004586 /* acquire the wakelock to avoid the apps suspend during the scan. To
4587 * address the following issues.
4588 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4589 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4590 * for long time, this result in apps running at full power for long time.
4591 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4592 * be stuck in full power because of resume BMPS
4593 */
4594 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004595
4596 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 pAdapter->sessionId, &scanRequest, &scanId,
4598 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004599
Jeff Johnson295189b2012-06-20 16:38:30 -07004600 if (eHAL_STATUS_SUCCESS != status)
4601 {
4602 hddLog(VOS_TRACE_LEVEL_ERROR,
4603 "%s: sme_ScanRequest returned error %d", __func__, status);
4604 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004605 if(eHAL_STATUS_RESOURCES == status)
4606 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004607 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 -07004608 status = -EBUSY;
4609 } else {
4610 status = -EIO;
4611 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004612 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 goto free_mem;
4614 }
4615
4616 pScanInfo->mScanPending = TRUE;
4617 pAdapter->request = request;
4618 pScanInfo->scanId = scanId;
4619
4620 complete(&pScanInfo->scan_req_completion_event);
4621
4622free_mem:
4623 if( scanRequest.SSIDs.SSIDList )
4624 {
4625 vos_mem_free(scanRequest.SSIDs.SSIDList);
4626 }
4627
4628 if( channelList )
4629 vos_mem_free( channelList );
4630
4631 EXIT();
4632
4633 return status;
4634}
4635
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004636
4637void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4638{
4639 v_U8_t iniDot11Mode =
4640 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4641 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4642
4643 switch ( iniDot11Mode )
4644 {
4645 case eHDD_DOT11_MODE_AUTO:
4646 case eHDD_DOT11_MODE_11ac:
4647 case eHDD_DOT11_MODE_11ac_ONLY:
4648#ifdef WLAN_FEATURE_11AC
4649 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4650#else
4651 hddDot11Mode = eHDD_DOT11_MODE_11n;
4652#endif
4653 break;
4654 case eHDD_DOT11_MODE_11n:
4655 case eHDD_DOT11_MODE_11n_ONLY:
4656 hddDot11Mode = eHDD_DOT11_MODE_11n;
4657 break;
4658 default:
4659 hddDot11Mode = iniDot11Mode;
4660 break;
4661 }
4662 /* This call decides required channel bonding mode */
4663 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4664 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4665 operationChannel);
4666}
4667
Jeff Johnson295189b2012-06-20 16:38:30 -07004668/*
4669 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304670 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304672int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004673 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004674{
4675 int status = 0;
4676 hdd_wext_state_t *pWextState;
4677 v_U32_t roamId;
4678 tCsrRoamProfile *pRoamProfile;
4679 eMib_dot11DesiredBssType connectedBssType;
4680 eCsrAuthType RSNAuthType;
4681
4682 ENTER();
4683
4684 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304685
Jeff Johnson295189b2012-06-20 16:38:30 -07004686 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4687 {
4688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4689 return -EINVAL;
4690 }
4691
4692 pRoamProfile = &pWextState->roamProfile;
4693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304694 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004696 int ret = 0;
4697 hdd_station_ctx_t *pHddStaCtx;
4698 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4699 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4700
4701 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4702 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4703 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004704 {
4705 /* Issue disconnect to CSR */
4706 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304707 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004708 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4709 pAdapter->sessionId,
4710 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4711 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004712 ret = wait_for_completion_interruptible_timeout(
4713 &pAdapter->disconnect_comp_var,
4714 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4715 if (0 == ret)
4716 {
4717 VOS_ASSERT(0);
4718 }
4719 }
4720 }
4721 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4722 {
4723 ret = wait_for_completion_interruptible_timeout(
4724 &pAdapter->disconnect_comp_var,
4725 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4726 if (0 == ret)
4727 {
4728 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004729 }
4730 }
4731
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304732 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004733 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4734 {
4735 /*QoS not enabled in cfg file*/
4736 pRoamProfile->uapsd_mask = 0;
4737 }
4738 else
4739 {
4740 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304741 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004742 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4743 }
4744
4745 pRoamProfile->SSIDs.numOfSSIDs = 1;
4746 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4747 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304748 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004749 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4750 ssid, ssid_len);
4751
4752 if (bssid)
4753 {
4754 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4755 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4756 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304757 /* Save BSSID in seperate variable as well, as RoamProfile
4758 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 case of join failure we should send valid BSSID to supplicant
4760 */
4761 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4762 WNI_CFG_BSSID_LEN);
4763 }
4764
4765 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4766 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304767 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004768 /*set gen ie*/
4769 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4770 /*set auth*/
4771 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4772 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004773#ifdef FEATURE_WLAN_WAPI
4774 if (pAdapter->wapi_info.nWapiMode)
4775 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004776 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004777 switch (pAdapter->wapi_info.wapiAuthMode)
4778 {
4779 case WAPI_AUTH_MODE_PSK:
4780 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004781 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004782 pAdapter->wapi_info.wapiAuthMode);
4783 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4784 break;
4785 }
4786 case WAPI_AUTH_MODE_CERT:
4787 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004788 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004789 pAdapter->wapi_info.wapiAuthMode);
4790 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4791 break;
4792 }
4793 } // End of switch
4794 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4795 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4796 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004797 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 pRoamProfile->AuthType.numEntries = 1;
4799 pRoamProfile->EncryptionType.numEntries = 1;
4800 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4801 pRoamProfile->mcEncryptionType.numEntries = 1;
4802 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4803 }
4804 }
4805#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304806#ifdef WLAN_FEATURE_GTK_OFFLOAD
4807 /* Initializing gtkOffloadRequestParams */
4808 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4809 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4810 {
4811 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4812 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4813 0, sizeof (tSirGtkOffloadParams));
4814 }
4815#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004816 pRoamProfile->csrPersona = pAdapter->device_mode;
4817
Jeff Johnson32d95a32012-09-10 13:15:23 -07004818 if( operatingChannel )
4819 {
4820 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4821 pRoamProfile->ChannelInfo.numOfChannels = 1;
4822 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004823 else
4824 {
4825 pRoamProfile->ChannelInfo.ChannelList = NULL;
4826 pRoamProfile->ChannelInfo.numOfChannels = 0;
4827 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004828 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4829 {
4830 hdd_select_cbmode(pAdapter,operatingChannel);
4831 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004832 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4833 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304834 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004835 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004836 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4837 */
4838 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4839 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4840 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304841
4842 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 pAdapter->sessionId, pRoamProfile, &roamId);
4844
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004845 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304846 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4847
4848 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004849 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4850 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4851 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304852 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004853 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304854 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004855
4856 pRoamProfile->ChannelInfo.ChannelList = NULL;
4857 pRoamProfile->ChannelInfo.numOfChannels = 0;
4858
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 }
4860 else
4861 {
4862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4863 return -EINVAL;
4864 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004865 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 return status;
4867}
4868
4869/*
4870 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4871 * This function is used to set the authentication type (OPEN/SHARED).
4872 *
4873 */
4874static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4875 enum nl80211_auth_type auth_type)
4876{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304877 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004878 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4879
4880 ENTER();
4881
4882 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304883 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004884 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304886 hddLog(VOS_TRACE_LEVEL_INFO,
4887 "%s: set authentication type to AUTOSWITCH", __func__);
4888 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4889 break;
4890
4891 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004892#ifdef WLAN_FEATURE_VOWIFI_11R
4893 case NL80211_AUTHTYPE_FT:
4894#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304895 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 "%s: set authentication type to OPEN", __func__);
4897 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4898 break;
4899
4900 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304901 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004902 "%s: set authentication type to SHARED", __func__);
4903 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4904 break;
4905#ifdef FEATURE_WLAN_CCX
4906 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304907 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 "%s: set authentication type to CCKM WPA", __func__);
4909 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4910 break;
4911#endif
4912
4913
4914 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304915 hddLog(VOS_TRACE_LEVEL_ERROR,
4916 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 auth_type);
4918 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4919 return -EINVAL;
4920 }
4921
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304922 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 pHddStaCtx->conn_info.authType;
4924 return 0;
4925}
4926
4927/*
4928 * FUNCTION: wlan_hdd_set_akm_suite
4929 * This function is used to set the key mgmt type(PSK/8021x).
4930 *
4931 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304932static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004933 u32 key_mgmt
4934 )
4935{
4936 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4937 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304938
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 /*set key mgmt type*/
4940 switch(key_mgmt)
4941 {
4942 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05304943#ifdef WLAN_FEATURE_VOWIFI_11R
4944 case WLAN_AKM_SUITE_FT_PSK:
4945#endif
4946 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07004947 __func__);
4948 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
4949 break;
4950
4951 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05304952#ifdef WLAN_FEATURE_VOWIFI_11R
4953 case WLAN_AKM_SUITE_FT_8021X:
4954#endif
4955 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 __func__);
4957 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
4958 break;
4959#ifdef FEATURE_WLAN_CCX
4960#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
4961#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
4962 case WLAN_AKM_SUITE_CCKM:
4963 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
4964 __func__);
4965 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
4966 break;
4967#endif
4968
4969 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304970 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004971 __func__, key_mgmt);
4972 return -EINVAL;
4973
4974 }
4975 return 0;
4976}
4977
4978/*
4979 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304980 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 * (NONE/WEP40/WEP104/TKIP/CCMP).
4982 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304983static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
4984 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 bool ucast
4986 )
4987{
4988 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304989 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4991
4992 ENTER();
4993
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304994 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304996 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 __func__, cipher);
4998 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4999 }
5000 else
5001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305002
Jeff Johnson295189b2012-06-20 16:38:30 -07005003 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305004 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005005 {
5006 case IW_AUTH_CIPHER_NONE:
5007 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5008 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305009
Jeff Johnson295189b2012-06-20 16:38:30 -07005010 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305011 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305013
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305015 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305017
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 case WLAN_CIPHER_SUITE_TKIP:
5019 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5020 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 case WLAN_CIPHER_SUITE_CCMP:
5023 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5024 break;
5025#ifdef FEATURE_WLAN_WAPI
5026 case WLAN_CIPHER_SUITE_SMS4:
5027 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5028 break;
5029#endif
5030
5031#ifdef FEATURE_WLAN_CCX
5032 case WLAN_CIPHER_SUITE_KRK:
5033 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5034 break;
5035#endif
5036 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005038 __func__, cipher);
5039 return -EOPNOTSUPP;
5040 }
5041 }
5042
5043 if (ucast)
5044 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 __func__, encryptionType);
5047 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5048 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305049 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 encryptionType;
5051 }
5052 else
5053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 __func__, encryptionType);
5056 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5057 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5058 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5059 }
5060
5061 return 0;
5062}
5063
5064
5065/*
5066 * FUNCTION: wlan_hdd_cfg80211_set_ie
5067 * This function is used to parse WPA/RSN IE's.
5068 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5070 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 size_t ie_len
5072 )
5073{
5074 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5075 u8 *genie = ie;
5076 v_U16_t remLen = ie_len;
5077#ifdef FEATURE_WLAN_WAPI
5078 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5079 u16 *tmp;
5080 v_U16_t akmsuiteCount;
5081 int *akmlist;
5082#endif
5083 ENTER();
5084
5085 /* clear previous assocAddIE */
5086 pWextState->assocAddIE.length = 0;
5087 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5088
5089 while (remLen >= 2)
5090 {
5091 v_U16_t eLen = 0;
5092 v_U8_t elementId;
5093 elementId = *genie++;
5094 eLen = *genie++;
5095 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096
5097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305099
5100 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305102 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005103 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 -07005104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 "%s: Invalid WPA IE", __func__);
5107 return -EINVAL;
5108 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 {
5111 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305112 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005113 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305114
Jeff Johnson295189b2012-06-20 16:38:30 -07005115 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5116 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005117 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5118 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 VOS_ASSERT(0);
5120 return -ENOMEM;
5121 }
5122 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5123 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5124 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305125
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5127 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5128 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5129 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305130 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5131 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5133 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5134 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5135 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5136 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5137 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305138 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5139 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 /*Consider P2P IE, only for P2P Client */
5141 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5142 {
5143 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305144 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305146
Jeff Johnson295189b2012-06-20 16:38:30 -07005147 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5148 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005149 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5150 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005151 VOS_ASSERT(0);
5152 return -ENOMEM;
5153 }
5154 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5155 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5156 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305157
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5159 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005161#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305162 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5163 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 /*Consider WFD IE, only for P2P Client */
5165 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5166 {
5167 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305168 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005169 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305170
Jeff Johnson295189b2012-06-20 16:38:30 -07005171 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5172 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005173 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5174 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 VOS_ASSERT(0);
5176 return -ENOMEM;
5177 }
5178 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5179 // WPS IE + P2P IE + WFD IE
5180 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5181 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305182
Jeff Johnson295189b2012-06-20 16:38:30 -07005183 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5184 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5185 }
5186#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005187 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005189 HS20_OUI_TYPE_SIZE)) )
5190 {
5191 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305192 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005193 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005194
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005195 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5196 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005197 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5198 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005199 VOS_ASSERT(0);
5200 return -ENOMEM;
5201 }
5202 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5203 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005204
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005205 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5206 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5207 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005208
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 break;
5210 case DOT11F_EID_RSN:
5211 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5212 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5213 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5214 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5215 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5216 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005217 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5218 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305219 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005220 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305221 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005222 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305223
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005224 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5225 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005226 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5227 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005228 VOS_ASSERT(0);
5229 return -ENOMEM;
5230 }
5231 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5232 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305233
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005234 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5235 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5236 break;
5237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005238#ifdef FEATURE_WLAN_WAPI
5239 case WLAN_EID_WAPI:
5240 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5241 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5242 pAdapter->wapi_info.nWapiMode);
5243 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 akmsuiteCount = WPA_GET_LE16(tmp);
5246 tmp = tmp + 1;
5247 akmlist = (int *)(tmp);
5248 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5249 {
5250 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5251 }
5252 else
5253 {
5254 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5255 VOS_ASSERT(0);
5256 return -EINVAL;
5257 }
5258
5259 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5260 {
5261 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005262 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305266 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005268 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005269 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5270 }
5271 break;
5272#endif
5273 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305274 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005276 /* when Unknown IE is received we should break and continue
5277 * to the next IE in the buffer instead we were returning
5278 * so changing this to break */
5279 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005280 }
5281 genie += eLen;
5282 remLen -= eLen;
5283 }
5284 EXIT();
5285 return 0;
5286}
5287
5288/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305289 * FUNCTION: hdd_isWPAIEPresent
5290 * Parse the received IE to find the WPA IE
5291 *
5292 */
5293static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5294{
5295 v_U8_t eLen = 0;
5296 v_U16_t remLen = ie_len;
5297 v_U8_t elementId = 0;
5298
5299 while (remLen >= 2)
5300 {
5301 elementId = *ie++;
5302 eLen = *ie++;
5303 remLen -= 2;
5304 if (eLen > remLen)
5305 {
5306 hddLog(VOS_TRACE_LEVEL_ERROR,
5307 "%s: IE length is wrong %d", __func__, eLen);
5308 return FALSE;
5309 }
5310 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5311 {
5312 /* OUI - 0x00 0X50 0XF2
5313 WPA Information Element - 0x01
5314 WPA version - 0x01*/
5315 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5316 return TRUE;
5317 }
5318 ie += eLen;
5319 remLen -= eLen;
5320 }
5321 return FALSE;
5322}
5323
5324/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005325 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305326 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 * parameters during connect operation.
5328 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305329int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 struct cfg80211_connect_params *req
5331 )
5332{
5333 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305334 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 ENTER();
5336
5337 /*set wpa version*/
5338 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5339
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305340 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 {
5342 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305343 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305344 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305346 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005347 * since p2p ie is also put in same buffer.
5348 * */
5349 {
5350 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5351 }
5352 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5353 {
5354 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5355 }
5356 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305357
5358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 pWextState->wpaVersion);
5360
5361 /*set authentication type*/
5362 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5363
5364 if (0 > status)
5365 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305366 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 "%s: failed to set authentication type ", __func__);
5368 return status;
5369 }
5370
5371 /*set key mgmt type*/
5372 if (req->crypto.n_akm_suites)
5373 {
5374 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5375 if (0 > status)
5376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005378 __func__);
5379 return status;
5380 }
5381 }
5382
5383 /*set pairwise cipher type*/
5384 if (req->crypto.n_ciphers_pairwise)
5385 {
5386 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5387 req->crypto.ciphers_pairwise[0], true);
5388 if (0 > status)
5389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305390 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005391 "%s: failed to set unicast cipher type", __func__);
5392 return status;
5393 }
5394 }
5395 else
5396 {
5397 /*Reset previous cipher suite to none*/
5398 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5399 if (0 > status)
5400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305401 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005402 "%s: failed to set unicast cipher type", __func__);
5403 return status;
5404 }
5405 }
5406
5407 /*set group cipher type*/
5408 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5409 false);
5410
5411 if (0 > status)
5412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005414 __func__);
5415 return status;
5416 }
5417
Chet Lanctot186b5732013-03-18 10:26:30 -07005418#ifdef WLAN_FEATURE_11W
5419 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5420#endif
5421
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5423 if (req->ie_len)
5424 {
5425 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5426 if ( 0 > status)
5427 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 __func__);
5430 return status;
5431 }
5432 }
5433
5434 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 {
5437 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5438 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5439 )
5440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305441 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5443 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 __func__);
5446 return -EOPNOTSUPP;
5447 }
5448 else
5449 {
5450 u8 key_len = req->key_len;
5451 u8 key_idx = req->key_idx;
5452
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 && (CSR_MAX_NUM_KEY > key_idx)
5455 )
5456 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305457 hddLog(VOS_TRACE_LEVEL_INFO,
5458 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 __func__, key_idx, key_len);
5460 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305461 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305463 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 (u8)key_len;
5465 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5466 }
5467 }
5468 }
5469 }
5470
5471 return status;
5472}
5473
5474/*
5475 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305476 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 * parameters during connect operation.
5478 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305479static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 struct net_device *ndev,
5481 struct cfg80211_connect_params *req
5482 )
5483{
5484 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305485 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005486 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5487 hdd_context_t *pHddCtx = NULL;
5488
5489 ENTER();
5490
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5493
5494 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5495 {
5496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5497 "%s:LOGP in Progress. Ignore!!!", __func__);
5498 return -EAGAIN;
5499 }
5500
5501#ifdef WLAN_BTAMP_FEATURE
5502 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005507 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 }
5509#endif
5510 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305511 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005512
5513 if ( 0 > status)
5514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 __func__);
5517 return status;
5518 }
5519
5520 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005521 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5523 (vos_concurrent_sessions_running()))
5524 {
5525 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5526
5527 if (NULL != pVosContext)
5528 {
5529 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5530 if(NULL != pHddCtx)
5531 {
5532 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5533 }
5534 }
5535 }
5536
Mohit Khanna765234a2012-09-11 15:08:35 -07005537 if ( req->channel )
5538 {
5539 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5540 req->ssid_len, req->bssid,
5541 req->channel->hw_value);
5542 }
5543 else
5544 {
5545 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5546 req->ssid_len, req->bssid,
5547 0);
5548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005549
5550 if (0 > status)
5551 {
5552 //ReEnable BMPS if disabled
5553 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5554 (NULL != pHddCtx))
5555 {
5556 //ReEnable Bmps and Imps back
5557 hdd_enable_bmps_imps(pHddCtx);
5558 }
5559
5560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5561 return status;
5562 }
5563 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5564 EXIT();
5565 return status;
5566}
5567
5568
5569/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305570 * FUNCTION: wlan_hdd_disconnect
5571 * This function is used to issue a disconnect request to SME
5572 */
5573int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5574{
5575 int status = 0;
5576 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5577 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5578 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5579 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5580 /*issue disconnect*/
5581 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5582 pAdapter->sessionId, reason);
5583
5584 if ( 0 != status )
5585 {
5586 hddLog(VOS_TRACE_LEVEL_ERROR,
5587 "%s csrRoamDisconnect failure, returned %d \n",
5588 __func__, (int)status );
5589 return -EINVAL;
5590 }
5591 wait_for_completion_interruptible_timeout(
5592 &pAdapter->disconnect_comp_var,
5593 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5594 /*stop tx queues*/
5595 netif_tx_disable(pAdapter->dev);
5596 netif_carrier_off(pAdapter->dev);
5597 return status;
5598}
5599
5600
5601/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 * FUNCTION: wlan_hdd_cfg80211_disconnect
5603 * This function is used to issue a disconnect request to SME
5604 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305605static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 struct net_device *dev,
5607 u16 reason
5608 )
5609{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5611 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5613 int status = 0;
5614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005615#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005616 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005617 tANI_U8 staIdx;
5618#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305619
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305621
5622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 __func__,pAdapter->device_mode);
5624
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5626 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005627
5628 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5629 {
5630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5631 "%s:LOGP in Progress. Ignore!!!",__func__);
5632 return -EAGAIN;
5633 }
5634 if (NULL != pRoamProfile)
5635 {
5636 /*issue disconnect request to SME, if station is in connected state*/
5637 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5638 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305639 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5641 switch(reason)
5642 {
5643 case WLAN_REASON_MIC_FAILURE:
5644 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5645 break;
5646
5647 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5648 case WLAN_REASON_DISASSOC_AP_BUSY:
5649 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5650 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5651 break;
5652
5653 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5654 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5655 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5656 break;
5657
5658 case WLAN_REASON_DEAUTH_LEAVING:
5659 default:
5660 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5661 break;
5662 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005663
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005664#ifdef FEATURE_WLAN_TDLS
5665 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005666 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005667 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005668 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5669 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005670 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005671 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005672 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005673 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005674 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005675 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005676 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005677 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005678 pAdapter->sessionId,
5679 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005680 }
5681 }
5682#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305683 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5684 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 {
5686 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305687 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 __func__, (int)status );
5689 return -EINVAL;
5690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 }
5692 }
5693 else
5694 {
5695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5696 }
5697
5698 return status;
5699}
5700
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305701
Jeff Johnson295189b2012-06-20 16:38:30 -07005702/*
5703 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305704 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 * settings in IBSS mode.
5706 */
5707static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 struct cfg80211_ibss_params *params
5710 )
5711{
5712 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305713 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5715 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305716
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 ENTER();
5718
5719 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5720
5721 if (params->ie_len && ( NULL != params->ie) )
5722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 {
5725 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5726 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5727 }
5728 else
5729 {
5730 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5731 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5732 }
5733 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5734
5735 if (0 > status)
5736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 __func__);
5739 return status;
5740 }
5741 }
5742
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743 pWextState->roamProfile.AuthType.authType[0] =
5744 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5746
5747 if (params->privacy)
5748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749 /* Security enabled IBSS, At this time there is no information available
5750 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305752 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 *enable privacy bit in beacons */
5756
5757 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5758 }
5759
5760 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5761 pWextState->roamProfile.EncryptionType.numEntries = 1;
5762 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5763
5764 return status;
5765}
5766
5767/*
5768 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305769 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305771static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 struct net_device *dev,
5773 struct cfg80211_ibss_params *params
5774 )
5775{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005777 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5778 tCsrRoamProfile *pRoamProfile;
5779 int status;
5780 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5781
5782 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305783
5784 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5786
5787 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5788 {
5789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5790 "%s:LOGP in Progress. Ignore!!!", __func__);
5791 return -EAGAIN;
5792 }
5793
5794 if (NULL == pWextState)
5795 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 __func__);
5798 return -EIO;
5799 }
5800
5801 pRoamProfile = &pWextState->roamProfile;
5802
5803 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5804 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 "%s Interface type is not set to IBSS \n", __func__);
5807 return -EINVAL;
5808 }
5809
5810 /* Set Channel */
5811 if (NULL != params->channel)
5812 {
5813 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005814 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5815 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5816 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5817 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005818
5819 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305820 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 ieee80211_frequency_to_channel(params->channel->center_freq);
5822
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005823
5824 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5825 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5828 __func__);
5829 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005831
5832 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005834 if (channelNum == validChan[indx])
5835 {
5836 break;
5837 }
5838 }
5839 if (indx >= numChans)
5840 {
5841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 __func__, channelNum);
5843 return -EINVAL;
5844 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005845 /* Set the Operational Channel */
5846 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5847 channelNum);
5848 pRoamProfile->ChannelInfo.numOfChannels = 1;
5849 pHddStaCtx->conn_info.operationChannel = channelNum;
5850 pRoamProfile->ChannelInfo.ChannelList =
5851 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 }
5853
5854 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 if (status < 0)
5857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305858 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 __func__);
5860 return status;
5861 }
5862
5863 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005865 params->ssid_len, params->bssid,
5866 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005867
5868 if (0 > status)
5869 {
5870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5871 return status;
5872 }
5873
5874 return 0;
5875}
5876
5877/*
5878 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305879 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 struct net_device *dev
5883 )
5884{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5887 tCsrRoamProfile *pRoamProfile;
5888
5889 ENTER();
5890
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005891 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5892 {
5893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5894 "%s:LOGP in Progress. Ignore!!!", __func__);
5895 return -EAGAIN;
5896 }
5897
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5899 if (NULL == pWextState)
5900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 __func__);
5903 return -EIO;
5904 }
5905
5906 pRoamProfile = &pWextState->roamProfile;
5907
5908 /* Issue disconnect only if interface type is set to IBSS */
5909 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 __func__);
5913 return -EINVAL;
5914 }
5915
5916 /* Issue Disconnect request */
5917 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5918 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5919 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5920
5921 return 0;
5922}
5923
5924/*
5925 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5926 * This function is used to set the phy parameters
5927 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5928 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305929static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 u32 changed)
5931{
5932 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5933 tHalHandle hHal = pHddCtx->hHal;
5934
5935 ENTER();
5936
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005937 if ( pHddCtx->isLogpInProgress )
5938 {
5939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5940 "%s:LOGP in Progress. Ignore!!!", __func__);
5941 return -EAGAIN;
5942 }
5943
Jeff Johnson295189b2012-06-20 16:38:30 -07005944 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5945 {
5946 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5947 WNI_CFG_RTS_THRESHOLD_STAMAX :
5948 wiphy->rts_threshold;
5949
5950 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305951 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305953 hddLog(VOS_TRACE_LEVEL_ERROR,
5954 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 __func__, rts_threshold);
5956 return -EINVAL;
5957 }
5958
5959 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
5960 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305963 hddLog(VOS_TRACE_LEVEL_ERROR,
5964 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 __func__, rts_threshold);
5966 return -EIO;
5967 }
5968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305969 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 rts_threshold);
5971 }
5972
5973 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
5974 {
5975 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
5976 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
5977 wiphy->frag_threshold;
5978
5979 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305980 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305982 hddLog(VOS_TRACE_LEVEL_ERROR,
5983 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 frag_threshold);
5985 return -EINVAL;
5986 }
5987
5988 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
5989 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305992 hddLog(VOS_TRACE_LEVEL_ERROR,
5993 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 __func__, frag_threshold);
5995 return -EIO;
5996 }
5997
5998 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
5999 frag_threshold);
6000 }
6001
6002 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6003 || (changed & WIPHY_PARAM_RETRY_LONG))
6004 {
6005 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6006 wiphy->retry_short :
6007 wiphy->retry_long;
6008
6009 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6010 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 __func__, retry_value);
6014 return -EINVAL;
6015 }
6016
6017 if (changed & WIPHY_PARAM_RETRY_SHORT)
6018 {
6019 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6020 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306021 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023 hddLog(VOS_TRACE_LEVEL_ERROR,
6024 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 __func__, retry_value);
6026 return -EIO;
6027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306028 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 __func__, retry_value);
6030 }
6031 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6032 {
6033 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6034 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037 hddLog(VOS_TRACE_LEVEL_ERROR,
6038 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 __func__, retry_value);
6040 return -EIO;
6041 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306042 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 __func__, retry_value);
6044 }
6045 }
6046
6047 return 0;
6048}
6049
6050/*
6051 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6052 * This function is used to set the txpower
6053 */
6054static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6055#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306056 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006057#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306058 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006059#endif
6060 int dbm)
6061{
6062 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6063 tHalHandle hHal = pHddCtx->hHal;
6064 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6065 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6066
6067 ENTER();
6068
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306069 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6070 dbm, ccmCfgSetCallback,
6071 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306073 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6075 return -EIO;
6076 }
6077
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006078 if ( pHddCtx->isLogpInProgress )
6079 {
6080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6081 "%s:LOGP in Progress. Ignore!!!", __func__);
6082 return -EAGAIN;
6083 }
6084
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6086 dbm);
6087
6088 switch(type)
6089 {
6090 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6091 /* Fall through */
6092 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6093 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6096 __func__);
6097 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 }
6099 break;
6100 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006102 __func__);
6103 return -EOPNOTSUPP;
6104 break;
6105 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6107 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 return -EIO;
6109 }
6110
6111 return 0;
6112}
6113
6114/*
6115 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6116 * This function is used to read the txpower
6117 */
6118static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6119{
6120
6121 hdd_adapter_t *pAdapter;
6122 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6123
Jeff Johnsone7245742012-09-05 17:12:55 -07006124 ENTER();
6125
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 if (NULL == pHddCtx)
6127 {
6128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6129 *dbm = 0;
6130 return -ENOENT;
6131 }
6132
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006133 if ( pHddCtx->isLogpInProgress )
6134 {
6135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6136 "%s:LOGP in Progress. Ignore!!!", __func__);
6137 return -EAGAIN;
6138 }
6139
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6141 if (NULL == pAdapter)
6142 {
6143 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6144 return -ENOENT;
6145 }
6146
6147 wlan_hdd_get_classAstats(pAdapter);
6148 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6149
Jeff Johnsone7245742012-09-05 17:12:55 -07006150 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006151 return 0;
6152}
6153
6154static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6155 u8* mac, struct station_info *sinfo)
6156{
6157 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6158 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6159 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6160 tANI_U8 rate_flags;
6161
6162 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6163 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006164
6165 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6166 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6167 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6168 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6169 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6170 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6171 tANI_U16 maxRate = 0;
6172 tANI_U16 myRate;
6173 tANI_U16 currentRate = 0;
6174 tANI_U8 maxSpeedMCS = 0;
6175 tANI_U8 maxMCSIdx = 0;
6176 tANI_U8 rateFlag = 1;
6177 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006178 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006179
Leo Chang6f8870f2013-03-26 18:11:36 -07006180#ifdef WLAN_FEATURE_11AC
6181 tANI_U32 vht_mcs_map;
6182 eDataRate11ACMaxMcs vhtMaxMcs;
6183#endif /* WLAN_FEATURE_11AC */
6184
Jeff Johnsone7245742012-09-05 17:12:55 -07006185 ENTER();
6186
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6188 (0 == ssidlen))
6189 {
6190 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6191 " Invalid ssidlen, %d", __func__, ssidlen);
6192 /*To keep GUI happy*/
6193 return 0;
6194 }
6195
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006196 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6197 {
6198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "%s:LOGP in Progress. Ignore!!!", __func__);
6200 return -EAGAIN;
6201 }
6202
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6204 sinfo->filled |= STATION_INFO_SIGNAL;
6205
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006206 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6208
6209 //convert to the UI units of 100kbps
6210 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6211
6212#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006213 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 -07006214 sinfo->signal,
6215 pCfg->reportMaxLinkSpeed,
6216 myRate,
6217 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006218 (int) pCfg->linkSpeedRssiMid,
6219 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006220 (int) rate_flags,
6221 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006222#endif //LINKSPEED_DEBUG_ENABLED
6223
6224 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6225 {
6226 // we do not want to necessarily report the current speed
6227 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6228 {
6229 // report the max possible speed
6230 rssidx = 0;
6231 }
6232 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6233 {
6234 // report the max possible speed with RSSI scaling
6235 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6236 {
6237 // report the max possible speed
6238 rssidx = 0;
6239 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006240 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 {
6242 // report middle speed
6243 rssidx = 1;
6244 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006245 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6246 {
6247 // report middle speed
6248 rssidx = 2;
6249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 else
6251 {
6252 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006253 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 }
6255 }
6256 else
6257 {
6258 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6259 hddLog(VOS_TRACE_LEVEL_ERROR,
6260 "%s: Invalid value for reportMaxLinkSpeed: %u",
6261 __func__, pCfg->reportMaxLinkSpeed);
6262 rssidx = 0;
6263 }
6264
6265 maxRate = 0;
6266
6267 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306268 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6269 OperationalRates, &ORLeng))
6270 {
6271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6272 /*To keep GUI happy*/
6273 return 0;
6274 }
6275
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 for (i = 0; i < ORLeng; i++)
6277 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006278 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 {
6280 /* Validate Rate Set */
6281 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6282 {
6283 currentRate = supported_data_rate[j].supported_rate[rssidx];
6284 break;
6285 }
6286 }
6287 /* Update MAX rate */
6288 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6289 }
6290
6291 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306292 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6293 ExtendedRates, &ERLeng))
6294 {
6295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6296 /*To keep GUI happy*/
6297 return 0;
6298 }
6299
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 for (i = 0; i < ERLeng; i++)
6301 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006302 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 {
6304 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6305 {
6306 currentRate = supported_data_rate[j].supported_rate[rssidx];
6307 break;
6308 }
6309 }
6310 /* Update MAX rate */
6311 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6312 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 /* Get MCS Rate Set -- but only if we are connected at MCS
6314 rates or if we are always reporting max speed or if we have
6315 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006316 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306318 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6319 MCSRates, &MCSLeng))
6320 {
6321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6322 /*To keep GUI happy*/
6323 return 0;
6324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006326#ifdef WLAN_FEATURE_11AC
6327 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306328 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006330 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306331 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006332 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006334 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006336 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006338 maxMCSIdx = 7;
6339 }
6340 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6341 {
6342 maxMCSIdx = 8;
6343 }
6344 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6345 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306346 //VHT20 is supporting 0~8
6347 if (rate_flags & eHAL_TX_RATE_VHT20)
6348 maxMCSIdx = 8;
6349 else
6350 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006351 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306352
6353 if (rate_flags & eHAL_TX_RATE_VHT80)
6354 {
6355 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6356 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6357 }
6358 else if (rate_flags & eHAL_TX_RATE_VHT40)
6359 {
6360 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6361 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6362 }
6363 else if (rate_flags & eHAL_TX_RATE_VHT20)
6364 {
6365 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6366 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6367 }
6368
Leo Chang6f8870f2013-03-26 18:11:36 -07006369 maxSpeedMCS = 1;
6370 if (currentRate > maxRate)
6371 {
6372 maxRate = currentRate;
6373 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306374
Leo Chang6f8870f2013-03-26 18:11:36 -07006375 }
6376 else
6377#endif /* WLAN_FEATURE_11AC */
6378 {
6379 if (rate_flags & eHAL_TX_RATE_HT40)
6380 {
6381 rateFlag |= 1;
6382 }
6383 if (rate_flags & eHAL_TX_RATE_SGI)
6384 {
6385 rateFlag |= 2;
6386 }
6387
6388 for (i = 0; i < MCSLeng; i++)
6389 {
6390 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6391 for (j = 0; j < temp; j++)
6392 {
6393 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6394 {
6395 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6396 break;
6397 }
6398 }
6399 if ((j < temp) && (currentRate > maxRate))
6400 {
6401 maxRate = currentRate;
6402 maxSpeedMCS = 1;
6403 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 }
6406 }
6407 }
6408
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306409 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6410 {
6411 maxRate = myRate;
6412 maxSpeedMCS = 1;
6413 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6414 }
6415
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006417 if (((maxRate < myRate) && (0 == rssidx)) ||
6418 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 {
6420 maxRate = myRate;
6421 if (rate_flags & eHAL_TX_RATE_LEGACY)
6422 {
6423 maxSpeedMCS = 0;
6424 }
6425 else
6426 {
6427 maxSpeedMCS = 1;
6428 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6429 }
6430 }
6431
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306432 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 {
6434 sinfo->txrate.legacy = maxRate;
6435#ifdef LINKSPEED_DEBUG_ENABLED
6436 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6437#endif //LINKSPEED_DEBUG_ENABLED
6438 }
6439 else
6440 {
6441 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006442#ifdef WLAN_FEATURE_11AC
6443 sinfo->txrate.nss = 1;
6444 if (rate_flags & eHAL_TX_RATE_VHT80)
6445 {
6446 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306447 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006448 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306449 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006450 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306451 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6452 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6453 }
6454 else if (rate_flags & eHAL_TX_RATE_VHT20)
6455 {
6456 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6457 }
6458#endif /* WLAN_FEATURE_11AC */
6459 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6460 {
6461 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6462 if (rate_flags & eHAL_TX_RATE_HT40)
6463 {
6464 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6465 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 if (rate_flags & eHAL_TX_RATE_SGI)
6468 {
6469 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6470 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306471
Jeff Johnson295189b2012-06-20 16:38:30 -07006472#ifdef LINKSPEED_DEBUG_ENABLED
6473 pr_info("Reporting MCS rate %d flags %x\n",
6474 sinfo->txrate.mcs,
6475 sinfo->txrate.flags );
6476#endif //LINKSPEED_DEBUG_ENABLED
6477 }
6478 }
6479 else
6480 {
6481 // report current rate instead of max rate
6482
6483 if (rate_flags & eHAL_TX_RATE_LEGACY)
6484 {
6485 //provide to the UI in units of 100kbps
6486 sinfo->txrate.legacy = myRate;
6487#ifdef LINKSPEED_DEBUG_ENABLED
6488 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6489#endif //LINKSPEED_DEBUG_ENABLED
6490 }
6491 else
6492 {
6493 //must be MCS
6494 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006495#ifdef WLAN_FEATURE_11AC
6496 sinfo->txrate.nss = 1;
6497 if (rate_flags & eHAL_TX_RATE_VHT80)
6498 {
6499 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6500 }
6501 else
6502#endif /* WLAN_FEATURE_11AC */
6503 {
6504 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 if (rate_flags & eHAL_TX_RATE_SGI)
6507 {
6508 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6509 }
6510 if (rate_flags & eHAL_TX_RATE_HT40)
6511 {
6512 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6513 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006514#ifdef WLAN_FEATURE_11AC
6515 else if (rate_flags & eHAL_TX_RATE_VHT80)
6516 {
6517 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6518 }
6519#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006520#ifdef LINKSPEED_DEBUG_ENABLED
6521 pr_info("Reporting actual MCS rate %d flags %x\n",
6522 sinfo->txrate.mcs,
6523 sinfo->txrate.flags );
6524#endif //LINKSPEED_DEBUG_ENABLED
6525 }
6526 }
6527 sinfo->filled |= STATION_INFO_TX_BITRATE;
6528
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006529 sinfo->tx_packets =
6530 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6531 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6532 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6533 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6534
6535 sinfo->tx_retries =
6536 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6537 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6538 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6539 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6540
6541 sinfo->tx_failed =
6542 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6543 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6544 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6545 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6546
6547 sinfo->filled |=
6548 STATION_INFO_TX_PACKETS |
6549 STATION_INFO_TX_RETRIES |
6550 STATION_INFO_TX_FAILED;
6551
6552 EXIT();
6553 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006554}
6555
6556static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6557 struct net_device *dev, bool mode, v_SINT_t timeout)
6558{
6559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306560 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 VOS_STATUS vos_status;
6562
Jeff Johnsone7245742012-09-05 17:12:55 -07006563 ENTER();
6564
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 if (NULL == pAdapter)
6566 {
6567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6568 return -ENODEV;
6569 }
6570
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306571 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6572 if (NULL == pHddCtx)
6573 {
6574 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6575 return -ENODEV;
6576 }
6577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306578 if ( pHddCtx->isLogpInProgress )
6579 {
6580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6581 "%s:LOGP in Progress. Ignore!!!", __func__);
6582 return -EAGAIN;
6583 }
6584
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306585 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6586 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6587 (pHddCtx->cfg_ini->fhostArpOffload) &&
6588 (eConnectionState_Associated ==
6589 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6590 {
6591 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6592 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6593 {
6594 hddLog(VOS_TRACE_LEVEL_INFO,
6595 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6596 __func__, vos_status);
6597 }
6598 }
6599
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 /**The get power cmd from the supplicant gets updated by the nl only
6601 *on successful execution of the function call
6602 *we are oppositely mapped w.r.t mode in the driver
6603 **/
6604 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6605
Jeff Johnsone7245742012-09-05 17:12:55 -07006606 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 if (VOS_STATUS_E_FAILURE == vos_status)
6608 {
6609 return -EINVAL;
6610 }
6611 return 0;
6612}
6613
6614
6615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6616static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6617 struct net_device *netdev,
6618 u8 key_index)
6619{
Jeff Johnsone7245742012-09-05 17:12:55 -07006620 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 return 0;
6622}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306623#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006624
6625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6626static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6627 struct net_device *dev,
6628 struct ieee80211_txq_params *params)
6629{
Jeff Johnsone7245742012-09-05 17:12:55 -07006630 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 return 0;
6632}
6633#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6634static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6635 struct ieee80211_txq_params *params)
6636{
Jeff Johnsone7245742012-09-05 17:12:55 -07006637 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 return 0;
6639}
6640#endif //LINUX_VERSION_CODE
6641
6642static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6643 struct net_device *dev, u8 *mac)
6644{
6645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006646 VOS_STATUS vos_status;
6647 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006648
Jeff Johnsone7245742012-09-05 17:12:55 -07006649 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6651 {
6652 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6653 return -EINVAL;
6654 }
6655
6656 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6657 {
6658 hddLog( LOGE,
6659 "%s: Wlan Load/Unload is in progress", __func__);
6660 return -EBUSY;
6661 }
6662
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006663 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6664 {
6665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6666 "%s:LOGP in Progress. Ignore!!!", __func__);
6667 return -EAGAIN;
6668 }
6669
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 )
6673 {
6674 if( NULL == mac )
6675 {
6676 v_U16_t i;
6677 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6678 {
6679 if(pAdapter->aStaInfo[i].isUsed)
6680 {
6681 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6682 hddLog(VOS_TRACE_LEVEL_INFO,
6683 "%s: Delete STA with MAC::"
6684 "%02x:%02x:%02x:%02x:%02x:%02x",
6685 __func__,
6686 macAddr[0], macAddr[1], macAddr[2],
6687 macAddr[3], macAddr[4], macAddr[5]);
6688 hdd_softap_sta_deauth(pAdapter, macAddr);
6689 }
6690 }
6691 }
6692 else
6693 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006694
6695 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6696 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6697 {
6698 hddLog(VOS_TRACE_LEVEL_INFO,
6699 "%s: Skip this DEL STA as this is not used::"
6700 "%02x:%02x:%02x:%02x:%02x:%02x",
6701 __func__,
6702 mac[0], mac[1], mac[2],
6703 mac[3], mac[4], mac[5]);
6704 return -ENOENT;
6705 }
6706
6707 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6708 {
6709 hddLog(VOS_TRACE_LEVEL_INFO,
6710 "%s: Skip this DEL STA as deauth is in progress::"
6711 "%02x:%02x:%02x:%02x:%02x:%02x",
6712 __func__,
6713 mac[0], mac[1], mac[2],
6714 mac[3], mac[4], mac[5]);
6715 return -ENOENT;
6716 }
6717
6718 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6719
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 hddLog(VOS_TRACE_LEVEL_INFO,
6721 "%s: Delete STA with MAC::"
6722 "%02x:%02x:%02x:%02x:%02x:%02x",
6723 __func__,
6724 mac[0], mac[1], mac[2],
6725 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006726
6727 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6728 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6729 {
6730 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6731 hddLog(VOS_TRACE_LEVEL_INFO,
6732 "%s: STA removal failed for ::"
6733 "%02x:%02x:%02x:%02x:%02x:%02x",
6734 __func__,
6735 mac[0], mac[1], mac[2],
6736 mac[3], mac[4], mac[5]);
6737 return -ENOENT;
6738 }
6739
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 }
6741 }
6742
6743 EXIT();
6744
6745 return 0;
6746}
6747
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006748static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6749 struct net_device *dev, u8 *mac, struct station_parameters *params)
6750{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006751 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006752#ifdef FEATURE_WLAN_TDLS
6753 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006754 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006755 mask = params->sta_flags_mask;
6756
6757 set = params->sta_flags_set;
6758
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006759#ifdef WLAN_FEATURE_TDLS_DEBUG
6760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6761 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6762 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6763#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006764
6765 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6766 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006767 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006768 }
6769 }
6770#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006771 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006772}
6773
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006774
6775#ifdef FEATURE_WLAN_LFR
6776static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006777 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006778{
6779#define MAX_PMKSAIDS_IN_CACHE 8
6780 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306781 static tANI_U32 i; // HDD Local Cache index
6782 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6784 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306785 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006786 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306787
Jeff Johnsone7245742012-09-05 17:12:55 -07006788 ENTER();
6789
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306790 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006791 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6792 {
6793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6794 return -EINVAL;
6795 }
6796
6797 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6798 {
6799 hddLog( LOGE,
6800 "%s: Wlan Load/Unload is in progress", __func__);
6801 return -EBUSY;
6802 }
6803
6804 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6805 {
6806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6807 "%s:LOGP in Progress. Ignore!!!", __func__);
6808 return -EAGAIN;
6809 }
6810
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306811 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006812 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6813
6814 for (j = 0; j < i; j++)
6815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306816 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006817 pmksa->bssid, WNI_CFG_BSSID_LEN))
6818 {
6819 /* BSSID matched previous entry. Overwrite it. */
6820 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306821 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006822 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306823 vos_mem_copy(PMKIDCache[j].PMKID,
6824 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006825 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306826 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006827 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006828 dump_bssid(pmksa->bssid);
6829 dump_pmkid(halHandle, pmksa->pmkid);
6830 break;
6831 }
6832 }
6833
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006834 /* Check we compared all entries,if then take the first slot now */
6835 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6836
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006837 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306838 {
6839 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6840 vos_mem_copy(PMKIDCache[i].BSSID,
6841 pmksa->bssid, ETHER_ADDR_LEN);
6842 vos_mem_copy(PMKIDCache[i].PMKID,
6843 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006844 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306845 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006846 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006847 dump_bssid(pmksa->bssid);
6848 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306849 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006850 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306851 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006852 }
6853
6854
6855 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006857 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306858 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006859 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006860 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306861 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6862 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006863 i );
6864 return 0;
6865}
6866
6867
6868static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006869 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006870{
Jeff Johnsone7245742012-09-05 17:12:55 -07006871 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006872 // TODO: Implement this later.
6873 return 0;
6874}
6875
6876static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6877{
Jeff Johnsone7245742012-09-05 17:12:55 -07006878 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006879 // TODO: Implement this later.
6880 return 0;
6881}
6882#endif
6883
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006884#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306885static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006886 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6887{
6888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6889 hdd_station_ctx_t *pHddStaCtx;
6890
6891 if (NULL == pAdapter)
6892 {
6893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6894 return -ENODEV;
6895 }
6896
6897 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6898
6899 // Added for debug on reception of Re-assoc Req.
6900 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006903 ftie->ie_len);
6904 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6905 }
6906
6907#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306908 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006909 ftie->ie_len);
6910#endif
6911
6912 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306913 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6914 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006915 ftie->ie_len);
6916 return 0;
6917}
6918#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006919
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306920#ifdef FEATURE_WLAN_SCAN_PNO
6921
6922void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
6923 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
6924{
6925 int ret;
6926 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
6927 hdd_context_t *pHddCtx;
6928
6929 if (NULL == pAdapter)
6930 {
6931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6932 "%s: HDD adapter is Null", __func__);
6933 return ;
6934 }
6935
6936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6937 if (NULL == pHddCtx)
6938 {
6939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6940 "%s: HDD context is Null!!!", __func__);
6941 return ;
6942 }
6943
6944 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
6945
6946 if (0 > ret)
6947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
6948
6949 cfg80211_sched_scan_results(pHddCtx->wiphy);
6950}
6951
6952/*
6953 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
6954 * NL interface to enable PNO
6955 */
6956static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
6957 struct net_device *dev, struct cfg80211_sched_scan_request *request)
6958{
6959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6960 tpSirPNOScanReq pPnoRequest = NULL;
6961 hdd_context_t *pHddCtx;
6962 tHalHandle hHal;
6963 v_U32_t i, indx, num_ch;
6964 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6965 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6966 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6967 eHalStatus status = eHAL_STATUS_FAILURE;
6968
6969 if (NULL == pAdapter)
6970 {
6971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6972 "%s: HDD adapter is Null", __func__);
6973 return -ENODEV;
6974 }
6975
6976 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6977 if (NULL == pHddCtx)
6978 {
6979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6980 "%s: HDD context is Null!!!", __func__);
6981 return -ENODEV;
6982 }
6983
6984 if (pHddCtx->isLogpInProgress)
6985 {
6986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6987 "%s: LOGP in Progress. Ignore!!!", __func__);
6988 return -EAGAIN;
6989 }
6990
6991 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6992 if (NULL == hHal)
6993 {
6994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6995 "%s: HAL context is Null!!!", __func__);
6996 return -EAGAIN;
6997 }
6998
6999 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7000 if (NULL == pPnoRequest)
7001 {
7002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7003 "%s: vos_mem_malloc failed", __func__);
7004 return -ENODEV;
7005 }
7006
7007 pPnoRequest->enable = 1; /*Enable PNO */
7008 pPnoRequest->ucNetworksCount = request->n_match_sets;
7009
7010 if (( !pPnoRequest->ucNetworksCount ) ||
7011 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7012 {
7013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7014 "Network input is not correct");
7015 goto error;
7016 }
7017
7018 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7019 {
7020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7021 "Incorrect number of channels");
7022 goto error;
7023 }
7024
7025 /* Framework provides one set of channels(all)
7026 * common for all saved profile */
7027 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7028 channels_allowed, &num_channels_allowed))
7029 {
7030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7031 "%s: failed to get valid channel list", __func__);
7032 goto error;
7033 }
7034 /* Checking each channel against allowed channel list */
7035 num_ch = 0;
7036 for (i = 0; i < request->n_channels; i++)
7037 {
7038 for (indx = 0; indx < num_channels_allowed; indx++)
7039 {
7040 if (request->channels[i]->hw_value == channels_allowed[indx])
7041 {
7042 valid_ch[num_ch++] = request->channels[i]->hw_value;
7043 break ;
7044 }
7045 }
7046 }
7047
7048 /* Filling per profile params */
7049 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7050 {
7051 pPnoRequest->aNetworks[i].ssId.length =
7052 request->match_sets[i].ssid.ssid_len;
7053
7054 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7055 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7056 {
7057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7058 "SSID Len %d is not correct for network %d",
7059 pPnoRequest->aNetworks[i].ssId.length, i);
7060 goto error;
7061 }
7062
7063 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7064 request->match_sets[i].ssid.ssid,
7065 request->match_sets[i].ssid.ssid_len);
7066 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7067 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7068 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7069
7070 /*Copying list of valid channel into request */
7071 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7072 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7073
7074 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7075 }
7076
7077 /* framework provides interval in ms */
7078 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7079 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7080 (request->interval)/1000;
7081 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7082 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7083
7084 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7085 pPnoRequest, pAdapter->sessionId,
7086 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7087 if (eHAL_STATUS_SUCCESS != status)
7088 {
7089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7090 "Failed to enable PNO");
7091 goto error;
7092 }
7093
7094error:
7095 vos_mem_free(pPnoRequest);
7096 return status;
7097}
7098
7099/*
7100 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7101 * NL interface to disable PNO
7102 */
7103static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7104 struct net_device *dev)
7105{
7106 eHalStatus status = eHAL_STATUS_FAILURE;
7107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7108 hdd_context_t *pHddCtx;
7109 tHalHandle hHal;
7110 tpSirPNOScanReq pPnoRequest = NULL;
7111
7112 ENTER();
7113
7114 if (NULL == pAdapter)
7115 {
7116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7117 "%s: HDD adapter is Null", __func__);
7118 return -ENODEV;
7119 }
7120
7121 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7122 if (NULL == pHddCtx)
7123 {
7124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7125 "%s: HDD context is Null!!!", __func__);
7126 return -ENODEV;
7127 }
7128
7129 if (pHddCtx->isLogpInProgress)
7130 {
7131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7132 "%s: LOGP in Progress. Ignore!!!", __func__);
7133 return -EAGAIN;
7134 }
7135
7136 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7137 if (NULL == hHal)
7138 {
7139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7140 "%s: HAL context is Null!!!", __func__);
7141 return -EAGAIN;
7142 }
7143
7144 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7145 if (NULL == pPnoRequest)
7146 {
7147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7148 "%s: vos_mem_malloc failed", __func__);
7149 return -ENODEV;
7150 }
7151
7152 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7153 pPnoRequest->enable = 0; /* Disable PNO */
7154 pPnoRequest->ucNetworksCount = 0;
7155
7156 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7157 pAdapter->sessionId,
7158 NULL, pAdapter);
7159 if (eHAL_STATUS_SUCCESS != status)
7160 {
7161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7162 "Failed to disabled PNO");
7163 }
7164
7165 vos_mem_free(pPnoRequest);
7166
7167 EXIT();
7168 return status;
7169}
7170
7171#endif /*FEATURE_WLAN_SCAN_PNO*/
7172
7173
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007174#ifdef FEATURE_WLAN_TDLS
7175static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7176 u8 *peer, u8 action_code, u8 dialog_token,
7177 u16 status_code, const u8 *buf, size_t len)
7178{
7179
7180 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7181 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007182 u8 peerMac[6];
7183 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007184 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007185 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007186 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007187
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007188 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007189 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007191 "Invalid arguments");
7192 return -EINVAL;
7193 }
7194
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007195 if (pHddCtx->isLogpInProgress)
7196 {
7197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7198 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007199 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007200 return -EBUSY;
7201 }
7202
Hoonki Lee27511902013-03-14 18:19:06 -07007203 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007204 {
Hoonki Lee27511902013-03-14 18:19:06 -07007205 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7206 "%s: TDLS mode is disabled OR not enabled in FW."
7207 MAC_ADDRESS_STR " action %d declined.",
7208 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007209 return -ENOTSUPP;
7210 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007211
Hoonki Lee27511902013-03-14 18:19:06 -07007212 /* other than teardown frame, other mgmt frames are not sent if disabled */
7213 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7214 {
7215 /* if tdls_mode is disabled to respond to peer's request */
7216 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7217 {
7218 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7219 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007220 " TDLS mode is disabled. action %d declined.",
7221 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007222
7223 return -ENOTSUPP;
7224 }
7225 }
7226
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007227 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7228 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007229 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007230 {
7231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007232 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007233 " TDLS setup is ongoing. action %d declined.",
7234 __func__, MAC_ADDR_ARRAY(peer), action_code);
7235 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007236 }
7237 }
7238
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007239 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7240 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007241 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007242 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007243 {
7244 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7245 we return error code at 'add_station()'. Hence we have this
7246 check again in addtion to add_station().
7247 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007248 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007249 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7251 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007252 " TDLS Max peer already connected. action %d declined.",
7253 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007254 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007255 }
7256 else
7257 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007258 /* maximum reached. tweak to send error code to peer and return
7259 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007260 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7262 "%s: " MAC_ADDRESS_STR
7263 " TDLS Max peer already connected send response status %d",
7264 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007265 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007266 /* fall through to send setup resp with failure status
7267 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007268 }
7269 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007270 else
7271 {
7272 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007273 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007274 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007275 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007277 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7278 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007279 return -EPERM;
7280 }
7281 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007282 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007283 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007284
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007285#ifdef WLAN_FEATURE_TDLS_DEBUG
7286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007287 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7288 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7289 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007290#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007291
Hoonki Leea34dd892013-02-05 22:56:02 -08007292 /*Except teardown responder will not be used so just make 0*/
7293 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007294 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007295 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007296
7297 hddTdlsPeer_t *pTdlsPeer;
7298 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7299
7300 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7301 responder = pTdlsPeer->is_responder;
7302 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007303 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7305 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7306 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7307 dialog_token, status_code, len);
7308 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007309 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007310 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007311
Hoonki Lee14621352013-04-16 17:51:19 -07007312 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7313 (SIR_MAC_TDLS_DIS_RSP == action_code))
7314 {
7315 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7316 {
7317 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7318 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7319 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7320 }
7321 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7322 }
7323
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007324 /* make sure doesn't call send_mgmt() while it is pending */
7325 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7326 {
7327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7328 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7329 __func__, MAC_ADDR_ARRAY(peer), action_code);
7330 return -EBUSY;
7331 }
7332
7333 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007334 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7335
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007336 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007337 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007338
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007339 if (VOS_STATUS_SUCCESS != status)
7340 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7342 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007343 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007344 wlan_hdd_tdls_check_bmps(pAdapter);
7345 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007346 }
7347
Hoonki Leed37cbb32013-04-20 00:31:14 -07007348 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7349 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7350
7351 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007352 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7354 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7355 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007356 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007357 wlan_hdd_tdls_check_bmps(pAdapter);
7358 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007359 }
7360
Gopichand Nakkala05922802013-03-14 12:23:19 -07007361 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007362 {
7363 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007364 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007365 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007366
Hoonki Leea34dd892013-02-05 22:56:02 -08007367 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7368 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007369 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007370 }
7371 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7372 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007373 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007374 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007375
7376 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007377error:
7378 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7379 because we already know that this transaction will be failed,
7380 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7381 to be safe, do not change the state mahine.
7382 */
7383 if(max_sta_failed == 0 &&
7384 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7385 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7386 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007387}
7388
7389static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7390 u8 *peer, enum nl80211_tdls_operation oper)
7391{
7392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7393 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307394#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7395 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7396 int status = 0;
7397 tANI_U8 staIdx;
7398#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007399#ifdef WLAN_FEATURE_TDLS_DEBUG
7400 const char *tdls_oper_str[]= {
7401 "NL80211_TDLS_DISCOVERY_REQ",
7402 "NL80211_TDLS_SETUP",
7403 "NL80211_TDLS_TEARDOWN",
7404 "NL80211_TDLS_ENABLE_LINK",
7405 "NL80211_TDLS_DISABLE_LINK",
7406 "NL80211_TDLS_UNKONW_OPER"};
7407#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007408 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007409
Chilam Ngc4244af2013-04-01 15:37:32 -07007410 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007411 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007413 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007414 return -EINVAL;
7415 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007416
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007417 if (pHddCtx->isLogpInProgress)
7418 {
7419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7420 "%s:LOGP in Progress. Ignore!!!", __func__);
7421 return -EBUSY;
7422 }
7423
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007424 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7425
7426 if ( NULL == pTdlsPeer ) {
7427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7428 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7429 return -EINVAL;
7430 }
7431
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007432#ifdef WLAN_FEATURE_TDLS_DEBUG
7433 if((int)oper > 4)
7434 oper = 5;
7435
7436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007437 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7438 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007439 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007440#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007441
7442 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007443 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007444 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007446 "TDLS Disabled in INI OR not enabled in FW. "
7447 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007448 return -ENOTSUPP;
7449 }
7450
7451 switch (oper) {
7452 case NL80211_TDLS_ENABLE_LINK:
7453 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007454 VOS_STATUS status;
7455
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007456 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7457 {
7458 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7459 MAC_ADDRESS_STR " failed",
7460 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7461 return -EINVAL;
7462 }
7463
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007464 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007465 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007466 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007467 /* start TDLS client registration with TL */
7468 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007469 if (VOS_STATUS_SUCCESS == status)
7470 {
Hoonki Lee14621352013-04-16 17:51:19 -07007471 if (pTdlsPeer->is_responder == 0)
7472 {
7473 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7474
7475 wlan_hdd_tdls_timer_restart(pAdapter,
7476 &pTdlsPeer->initiatorWaitTimeoutTimer,
7477 WAIT_TIME_TDLS_INITIATOR);
7478 /* suspend initiator TX until it receives direct packet from the
7479 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7480 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7481 &staId, NULL);
7482 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007483 wlan_hdd_tdls_increment_peer_count(pAdapter);
7484 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007485 wlan_hdd_tdls_check_bmps(pAdapter);
7486 }
7487
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007488 }
7489 break;
7490 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007491 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007492 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007493 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007494 long status;
7495
7496 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7497
Lee Hoonkic1262f22013-01-24 21:59:00 -08007498 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7499 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007500
7501 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7502 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7503 if (status <= 0)
7504 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007505 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7507 "%s: Del station failed status %ld",
7508 __func__, status);
7509 return -EPERM;
7510 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007511 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007512 }
7513 else
7514 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7516 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007517 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307518#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7519 if (pHddTdlsCtx->defer_link_lost_indication)
7520 {
7521 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7522 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7523 {
7524 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7525 if ( 0 != status)
7526 {
7527 hddLog(VOS_TRACE_LEVEL_ERROR,
7528 "%s wlan_hdd_disconnect failure, returned %d \n",
7529 __func__, (int)status );
7530 return -EINVAL;
7531 }
7532 }
7533 }
7534#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007535 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007536 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007537 case NL80211_TDLS_TEARDOWN:
7538 case NL80211_TDLS_SETUP:
7539 case NL80211_TDLS_DISCOVERY_REQ:
7540 /* We don't support in-driver setup/teardown/discovery */
7541 return -ENOTSUPP;
7542 default:
7543 return -ENOTSUPP;
7544 }
7545 return 0;
7546}
Chilam NG571c65a2013-01-19 12:27:36 +05307547
7548int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7549 struct net_device *dev, u8 *peer)
7550{
7551 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7552 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7553
7554 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7555 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7556}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007557#endif
7558
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307559#ifdef WLAN_FEATURE_GTK_OFFLOAD
7560/*
7561 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7562 * Callback rountine called upon receiving response for
7563 * get offload info
7564 */
7565void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7566 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7567{
7568
7569 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7570
7571 ENTER();
7572
7573 if (NULL == pAdapter)
7574 {
7575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7576 "%s: HDD adapter is Null", __func__);
7577 return ;
7578 }
7579
7580 if (NULL == pGtkOffloadGetInfoRsp)
7581 {
7582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7583 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7584 return ;
7585 }
7586
7587 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7588 {
7589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7590 "%s: wlan Failed to get replay counter value",
7591 __func__);
7592 return ;
7593 }
7594
7595 /* Update replay counter to NL */
7596 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7597 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7598}
7599
7600/*
7601 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7602 * This function is used to offload GTK rekeying job to the firmware.
7603 */
7604int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7605 struct cfg80211_gtk_rekey_data *data)
7606{
7607 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7608 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7609 hdd_station_ctx_t *pHddStaCtx;
7610 tHalHandle hHal;
7611 tpSirGtkOffloadParams pGtkOffloadReqParams;
7612 eHalStatus status = eHAL_STATUS_FAILURE;
7613
7614 ENTER();
7615
7616 if (NULL == pAdapter)
7617 {
7618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7619 "%s: HDD adapter is Null", __func__);
7620 return -ENODEV;
7621 }
7622
7623 if (NULL == pHddCtx)
7624 {
7625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7626 "%s: HDD context is Null!!!", __func__);
7627 return -ENODEV;
7628 }
7629
7630 if (pHddCtx->isLogpInProgress)
7631 {
7632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7633 "%s: LOGP in Progress. Ignore!!!", __func__);
7634 return -EAGAIN;
7635 }
7636
7637 if (pHddCtx->isLoadUnloadInProgress)
7638 {
7639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7640 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7641 return -EAGAIN;
7642 }
7643
7644 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7645 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7646 if (NULL == hHal)
7647 {
7648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7649 "%s: HAL context is Null!!!", __func__);
7650 return -EAGAIN;
7651 }
7652
7653 pGtkOffloadReqParams =
7654 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7655
7656 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7657 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7658 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7659 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7660 WNI_CFG_BSSID_LEN);
7661 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7662 sizeof (tANI_U64));
7663
7664 if (TRUE == pHddCtx->hdd_wlan_suspended)
7665 {
7666 /* if wlan is suspended, enable GTK offload directly from here */
7667 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7668 pAdapter->sessionId);
7669
7670 if (eHAL_STATUS_SUCCESS != status)
7671 {
7672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7673 "%s: sme_SetGTKOffload failed, returned %d",
7674 __func__, status);
7675 return status;
7676 }
7677 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7679 "%s: sme_SetGTKOffload successfull", __func__);
7680 }
7681 else
7682 {
7683 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7685 "%s: wlan not suspended GTKOffload request is stored",
7686 __func__);
7687 return eHAL_STATUS_SUCCESS;
7688 }
7689 return status;
7690}
7691#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7692
Jeff Johnson295189b2012-06-20 16:38:30 -07007693/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307694static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007695{
7696 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7697 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7698 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7699 .change_station = wlan_hdd_change_station,
7700#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7701 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7702 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7703 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007704#else
7705 .start_ap = wlan_hdd_cfg80211_start_ap,
7706 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7707 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007708#endif
7709 .change_bss = wlan_hdd_cfg80211_change_bss,
7710 .add_key = wlan_hdd_cfg80211_add_key,
7711 .get_key = wlan_hdd_cfg80211_get_key,
7712 .del_key = wlan_hdd_cfg80211_del_key,
7713 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007714#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007716#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 .scan = wlan_hdd_cfg80211_scan,
7718 .connect = wlan_hdd_cfg80211_connect,
7719 .disconnect = wlan_hdd_cfg80211_disconnect,
7720 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7721 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7722 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7723 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7724 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7726 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7727 .mgmt_tx = wlan_hdd_action,
7728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7729 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7730 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7731 .set_txq_params = wlan_hdd_set_txq_params,
7732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 .get_station = wlan_hdd_cfg80211_get_station,
7734 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7735 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007736 .add_station = wlan_hdd_cfg80211_add_station,
7737#ifdef FEATURE_WLAN_LFR
7738 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7739 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7740 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7741#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007742#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7743 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7744#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007745#ifdef FEATURE_WLAN_TDLS
7746 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7747 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7748#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307749#ifdef WLAN_FEATURE_GTK_OFFLOAD
7750 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7751#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307752#ifdef FEATURE_WLAN_SCAN_PNO
7753 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
7754 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
7755#endif /*FEATURE_WLAN_SCAN_PNO */
Jeff Johnson295189b2012-06-20 16:38:30 -07007756};
7757