blob: 7fff4861798c4019c2ffae02ac67f563dc9bf6be [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"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053086#include "wlan_hdd_wmm.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080087#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053088#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089
90#define g_mode_rates_size (12)
91#define a_mode_rates_size (8)
92#define FREQ_BASE_80211G (2407)
93#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070094#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070095#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
96 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
97
98#define HDD2GHZCHAN(freq, chan, flag) { \
99 .band = IEEE80211_BAND_2GHZ, \
100 .center_freq = (freq), \
101 .hw_value = (chan),\
102 .flags = (flag), \
103 .max_antenna_gain = 0 ,\
104 .max_power = 30, \
105}
106
107#define HDD5GHZCHAN(freq, chan, flag) { \
108 .band = IEEE80211_BAND_5GHZ, \
109 .center_freq = (freq), \
110 .hw_value = (chan),\
111 .flags = (flag), \
112 .max_antenna_gain = 0 ,\
113 .max_power = 30, \
114}
115
116#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
117{\
118 .bitrate = rate, \
119 .hw_value = rate_id, \
120 .flags = flag, \
121}
122
Lee Hoonkic1262f22013-01-24 21:59:00 -0800123#ifndef WLAN_FEATURE_TDLS_DEBUG
124#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
125#else
126#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
127#endif
128
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530129#ifdef WLAN_FEATURE_VOWIFI_11R
130#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
131#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
132#endif
133
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530134static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700135{
136 WLAN_CIPHER_SUITE_WEP40,
137 WLAN_CIPHER_SUITE_WEP104,
138 WLAN_CIPHER_SUITE_TKIP,
139#ifdef FEATURE_WLAN_CCX
140#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
141 WLAN_CIPHER_SUITE_KRK,
142 WLAN_CIPHER_SUITE_CCMP,
143#else
144 WLAN_CIPHER_SUITE_CCMP,
145#endif
146#ifdef FEATURE_WLAN_WAPI
147 WLAN_CIPHER_SUITE_SMS4,
148#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700149#ifdef WLAN_FEATURE_11W
150 WLAN_CIPHER_SUITE_AES_CMAC,
151#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700152};
153
154static inline int is_broadcast_ether_addr(const u8 *addr)
155{
156 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
157 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
158}
159
160static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530161{
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 HDD2GHZCHAN(2412, 1, 0) ,
163 HDD2GHZCHAN(2417, 2, 0) ,
164 HDD2GHZCHAN(2422, 3, 0) ,
165 HDD2GHZCHAN(2427, 4, 0) ,
166 HDD2GHZCHAN(2432, 5, 0) ,
167 HDD2GHZCHAN(2437, 6, 0) ,
168 HDD2GHZCHAN(2442, 7, 0) ,
169 HDD2GHZCHAN(2447, 8, 0) ,
170 HDD2GHZCHAN(2452, 9, 0) ,
171 HDD2GHZCHAN(2457, 10, 0) ,
172 HDD2GHZCHAN(2462, 11, 0) ,
173 HDD2GHZCHAN(2467, 12, 0) ,
174 HDD2GHZCHAN(2472, 13, 0) ,
175 HDD2GHZCHAN(2484, 14, 0) ,
176};
177
Jeff Johnson295189b2012-06-20 16:38:30 -0700178static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
179{
180 HDD2GHZCHAN(2412, 1, 0) ,
181 HDD2GHZCHAN(2437, 6, 0) ,
182 HDD2GHZCHAN(2462, 11, 0) ,
183};
Jeff Johnson295189b2012-06-20 16:38:30 -0700184
185static struct ieee80211_channel hdd_channels_5_GHZ[] =
186{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700187 HDD5GHZCHAN(4920, 240, 0) ,
188 HDD5GHZCHAN(4940, 244, 0) ,
189 HDD5GHZCHAN(4960, 248, 0) ,
190 HDD5GHZCHAN(4980, 252, 0) ,
191 HDD5GHZCHAN(5040, 208, 0) ,
192 HDD5GHZCHAN(5060, 212, 0) ,
193 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 HDD5GHZCHAN(5180, 36, 0) ,
195 HDD5GHZCHAN(5200, 40, 0) ,
196 HDD5GHZCHAN(5220, 44, 0) ,
197 HDD5GHZCHAN(5240, 48, 0) ,
198 HDD5GHZCHAN(5260, 52, 0) ,
199 HDD5GHZCHAN(5280, 56, 0) ,
200 HDD5GHZCHAN(5300, 60, 0) ,
201 HDD5GHZCHAN(5320, 64, 0) ,
202 HDD5GHZCHAN(5500,100, 0) ,
203 HDD5GHZCHAN(5520,104, 0) ,
204 HDD5GHZCHAN(5540,108, 0) ,
205 HDD5GHZCHAN(5560,112, 0) ,
206 HDD5GHZCHAN(5580,116, 0) ,
207 HDD5GHZCHAN(5600,120, 0) ,
208 HDD5GHZCHAN(5620,124, 0) ,
209 HDD5GHZCHAN(5640,128, 0) ,
210 HDD5GHZCHAN(5660,132, 0) ,
211 HDD5GHZCHAN(5680,136, 0) ,
212 HDD5GHZCHAN(5700,140, 0) ,
213 HDD5GHZCHAN(5745,149, 0) ,
214 HDD5GHZCHAN(5765,153, 0) ,
215 HDD5GHZCHAN(5785,157, 0) ,
216 HDD5GHZCHAN(5805,161, 0) ,
217 HDD5GHZCHAN(5825,165, 0) ,
218};
219
220static struct ieee80211_rate g_mode_rates[] =
221{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530222 HDD_G_MODE_RATETAB(10, 0x1, 0),
223 HDD_G_MODE_RATETAB(20, 0x2, 0),
224 HDD_G_MODE_RATETAB(55, 0x4, 0),
225 HDD_G_MODE_RATETAB(110, 0x8, 0),
226 HDD_G_MODE_RATETAB(60, 0x10, 0),
227 HDD_G_MODE_RATETAB(90, 0x20, 0),
228 HDD_G_MODE_RATETAB(120, 0x40, 0),
229 HDD_G_MODE_RATETAB(180, 0x80, 0),
230 HDD_G_MODE_RATETAB(240, 0x100, 0),
231 HDD_G_MODE_RATETAB(360, 0x200, 0),
232 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530234};
Jeff Johnson295189b2012-06-20 16:38:30 -0700235
236static struct ieee80211_rate a_mode_rates[] =
237{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 HDD_G_MODE_RATETAB(540, 0x800, 0),
246};
247
248static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
249{
250 .channels = hdd_channels_2_4_GHZ,
251 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
252 .band = IEEE80211_BAND_2GHZ,
253 .bitrates = g_mode_rates,
254 .n_bitrates = g_mode_rates_size,
255 .ht_cap.ht_supported = 1,
256 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
257 | IEEE80211_HT_CAP_GRN_FLD
258 | IEEE80211_HT_CAP_DSSSCCK40
259 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
260 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
261 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
262 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
263 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
264 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
265};
266
Jeff Johnson295189b2012-06-20 16:38:30 -0700267static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
268{
269 .channels = hdd_social_channels_2_4_GHZ,
270 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
271 .band = IEEE80211_BAND_2GHZ,
272 .bitrates = g_mode_rates,
273 .n_bitrates = g_mode_rates_size,
274 .ht_cap.ht_supported = 1,
275 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
276 | IEEE80211_HT_CAP_GRN_FLD
277 | IEEE80211_HT_CAP_DSSSCCK40
278 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
279 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
280 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
281 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
282 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
283 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
284};
Jeff Johnson295189b2012-06-20 16:38:30 -0700285
286static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
287{
288 .channels = hdd_channels_5_GHZ,
289 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
290 .band = IEEE80211_BAND_5GHZ,
291 .bitrates = a_mode_rates,
292 .n_bitrates = a_mode_rates_size,
293 .ht_cap.ht_supported = 1,
294 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
295 | IEEE80211_HT_CAP_GRN_FLD
296 | IEEE80211_HT_CAP_DSSSCCK40
297 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
298 | IEEE80211_HT_CAP_SGI_40
299 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
300 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
301 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
302 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
303 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
304 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
305};
306
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530307/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 TX/RX direction for each kind of interface */
309static const struct ieee80211_txrx_stypes
310wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
311 [NL80211_IFTYPE_STATION] = {
312 .tx = 0xffff,
313 .rx = BIT(SIR_MAC_MGMT_ACTION) |
314 BIT(SIR_MAC_MGMT_PROBE_REQ),
315 },
316 [NL80211_IFTYPE_AP] = {
317 .tx = 0xffff,
318 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
320 BIT(SIR_MAC_MGMT_PROBE_REQ) |
321 BIT(SIR_MAC_MGMT_DISASSOC) |
322 BIT(SIR_MAC_MGMT_AUTH) |
323 BIT(SIR_MAC_MGMT_DEAUTH) |
324 BIT(SIR_MAC_MGMT_ACTION),
325 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700326 [NL80211_IFTYPE_ADHOC] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
329 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
330 BIT(SIR_MAC_MGMT_PROBE_REQ) |
331 BIT(SIR_MAC_MGMT_DISASSOC) |
332 BIT(SIR_MAC_MGMT_AUTH) |
333 BIT(SIR_MAC_MGMT_DEAUTH) |
334 BIT(SIR_MAC_MGMT_ACTION),
335 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 [NL80211_IFTYPE_P2P_CLIENT] = {
337 .tx = 0xffff,
338 .rx = BIT(SIR_MAC_MGMT_ACTION) |
339 BIT(SIR_MAC_MGMT_PROBE_REQ),
340 },
341 [NL80211_IFTYPE_P2P_GO] = {
342 /* This is also same as for SoftAP */
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
346 BIT(SIR_MAC_MGMT_PROBE_REQ) |
347 BIT(SIR_MAC_MGMT_DISASSOC) |
348 BIT(SIR_MAC_MGMT_AUTH) |
349 BIT(SIR_MAC_MGMT_DEAUTH) |
350 BIT(SIR_MAC_MGMT_ACTION),
351 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700352};
353
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800355static const struct ieee80211_iface_limit
356wlan_hdd_iface_limit[] = {
357 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800358 /* max = 3 ; Our driver create two interfaces during driver init
359 * wlan0 and p2p0 interfaces. p2p0 is considered as station
360 * interface until a group is formed. In JB architecture, once the
361 * group is formed, interface type of p2p0 is changed to P2P GO or
362 * Client.
363 * When supplicant remove the group, it first issue a set interface
364 * cmd to change the mode back to Station. In JB this works fine as
365 * we advertize two station type interface during driver init.
366 * Some vendors create separate interface for P2P GO/Client,
367 * after group formation(Third one). But while group remove
368 * supplicant first tries to change the mode(3rd interface) to STATION
369 * But as we advertized only two sta type interfaces nl80211 was
370 * returning error for the third one which was leading to failure in
371 * delete interface. Ideally while removing the group, supplicant
372 * should not try to change the 3rd interface mode to Station type.
373 * Till we get a fix in wpa_supplicant, we advertize max STA
374 * interface type to 3
375 */
376 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800377 .types = BIT(NL80211_IFTYPE_STATION),
378 },
379 {
380 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700381 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800382 },
383 {
384 .max = 1,
385 .types = BIT(NL80211_IFTYPE_P2P_GO) |
386 BIT(NL80211_IFTYPE_P2P_CLIENT),
387 },
388};
389
390/* By default, only single channel concurrency is allowed */
391static struct ieee80211_iface_combination
392wlan_hdd_iface_combination = {
393 .limits = wlan_hdd_iface_limit,
394 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /*
396 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
397 * and p2p0 interfaces during driver init
398 * Some vendors create separate interface for P2P operations.
399 * wlan0: STA interface
400 * p2p0: P2P Device interface, action frames goes
401 * through this interface.
402 * p2p-xx: P2P interface, After GO negotiation this interface is
403 * created for p2p operations(GO/CLIENT interface).
404 */
405 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
407 .beacon_int_infra_match = false,
408};
409#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800410
Jeff Johnson295189b2012-06-20 16:38:30 -0700411static struct cfg80211_ops wlan_hdd_cfg80211_ops;
412
413/* Data rate 100KBPS based on IE Index */
414struct index_data_rate_type
415{
416 v_U8_t beacon_rate_index;
417 v_U16_t supported_rate[4];
418};
419
420/* 11B, 11G Rate table include Basic rate and Extended rate
421 The IDX field is the rate index
422 The HI field is the rate when RSSI is strong or being ignored
423 (in this case we report actual rate)
424 The MID field is the rate when RSSI is moderate
425 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
426 The LO field is the rate when RSSI is low
427 (in this case we don't report rates, actual current rate used)
428 */
429static const struct
430{
431 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700432 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700433} supported_data_rate[] =
434{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700435/* IDX HI HM LM LO (RSSI-based index */
436 {2, { 10, 10, 10, 0}},
437 {4, { 20, 20, 10, 0}},
438 {11, { 55, 20, 10, 0}},
439 {12, { 60, 55, 20, 0}},
440 {18, { 90, 55, 20, 0}},
441 {22, {110, 55, 20, 0}},
442 {24, {120, 90, 60, 0}},
443 {36, {180, 120, 60, 0}},
444 {44, {220, 180, 60, 0}},
445 {48, {240, 180, 90, 0}},
446 {66, {330, 180, 90, 0}},
447 {72, {360, 240, 90, 0}},
448 {96, {480, 240, 120, 0}},
449 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700450};
451
452/* MCS Based rate table */
453static struct index_data_rate_type supported_mcs_rate[] =
454{
455/* MCS L20 L40 S20 S40 */
456 {0, {65, 135, 72, 150}},
457 {1, {130, 270, 144, 300}},
458 {2, {195, 405, 217, 450}},
459 {3, {260, 540, 289, 600}},
460 {4, {390, 810, 433, 900}},
461 {5, {520, 1080, 578, 1200}},
462 {6, {585, 1215, 650, 1350}},
463 {7, {650, 1350, 722, 1500}}
464};
465
Leo Chang6f8870f2013-03-26 18:11:36 -0700466#ifdef WLAN_FEATURE_11AC
467
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530468#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700469
470struct index_vht_data_rate_type
471{
472 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530473 v_U16_t supported_VHT80_rate[2];
474 v_U16_t supported_VHT40_rate[2];
475 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700476};
477
478typedef enum
479{
480 DATA_RATE_11AC_MAX_MCS_7,
481 DATA_RATE_11AC_MAX_MCS_8,
482 DATA_RATE_11AC_MAX_MCS_9,
483 DATA_RATE_11AC_MAX_MCS_NA
484} eDataRate11ACMaxMcs;
485
486/* MCS Based VHT rate table */
487static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
488{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530489/* MCS L80 S80 L40 S40 L20 S40*/
490 {0, {293, 325}, {135, 150}, {65, 72}},
491 {1, {585, 650}, {270, 300}, {130, 144}},
492 {2, {878, 975}, {405, 450}, {195, 217}},
493 {3, {1170, 1300}, {540, 600}, {260, 289}},
494 {4, {1755, 1950}, {810, 900}, {390, 433}},
495 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
496 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
497 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
498 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
499 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700500};
501#endif /* WLAN_FEATURE_11AC */
502
Jeff Johnson295189b2012-06-20 16:38:30 -0700503extern struct net_device_ops net_ops_struct;
504
505/*
506 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530507 * This function is called by hdd_wlan_startup()
508 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700509 * This function is used to initialize and register wiphy structure.
510 */
511struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
512{
513 struct wiphy *wiphy;
514 ENTER();
515
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530516 /*
517 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 */
519 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
520
521 if (!wiphy)
522 {
523 /* Print error and jump into err label and free the memory */
524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
525 return NULL;
526 }
527
528 return wiphy;
529}
530
531/*
532 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530533 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700534 * private ioctl to change the band value
535 */
536int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
537{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530538 int i, j;
539 eNVChannelEnabledType channelEnabledState;
540
Jeff Johnsone7245742012-09-05 17:12:55 -0700541 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530542 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700543 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530544
545 if (NULL == wiphy->bands[i])
546 {
547 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
548 __func__, i);
549 continue;
550 }
551
552 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
553 {
554 struct ieee80211_supported_band *band = wiphy->bands[i];
555
556 channelEnabledState = vos_nv_getChannelEnabledState(
557 band->channels[j].hw_value);
558
559 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
560 {
561 // Enable Social channels for P2P
562 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
563 NV_CHANNEL_ENABLE == channelEnabledState)
564 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
565 else
566 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
567 continue;
568 }
569 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
570 {
571 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
572 continue;
573 }
574
575 if (NV_CHANNEL_DISABLE == channelEnabledState ||
576 NV_CHANNEL_INVALID == channelEnabledState)
577 {
578 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
579 }
580 else if (NV_CHANNEL_DFS == channelEnabledState)
581 {
582 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
583 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
584 }
585 else
586 {
587 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
588 |IEEE80211_CHAN_RADAR);
589 }
590 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 }
592 return 0;
593}
594/*
595 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530596 * This function is called by hdd_wlan_startup()
597 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 * This function is used to initialize and register wiphy structure.
599 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530600int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700601 struct wiphy *wiphy,
602 hdd_config_t *pCfg
603 )
604{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530605
606 int i, j;
607
Jeff Johnsone7245742012-09-05 17:12:55 -0700608 ENTER();
609
Jeff Johnson295189b2012-06-20 16:38:30 -0700610 /* Now bind the underlying wlan device with wiphy */
611 set_wiphy_dev(wiphy, dev);
612
613 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
614
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700615 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700616
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700617#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700618 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
619 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
620 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700621 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700622#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700623#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
624 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800625#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700626 || pCfg->isFastRoamIniFeatureEnabled
627#endif
628#ifdef FEATURE_WLAN_CCX
629 || pCfg->isCcxIniFeatureEnabled
630#endif
631 )
632 {
633 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
634 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800635#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800636#ifdef FEATURE_WLAN_TDLS
637 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
638 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
639#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530640#ifdef FEATURE_WLAN_SCAN_PNO
641 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
642 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
643 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
644#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800645
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700646 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
647 driver can still register regulatory callback and
648 it will get CRDA setting in wiphy->band[], but
649 driver need to determine what to do with both
650 regulatory settings */
651 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700652
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530653 wiphy->max_scan_ssids = MAX_SCAN_SSID;
654
Jeff Johnson295189b2012-06-20 16:38:30 -0700655 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
656
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530657 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
658
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530660 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 | BIT(NL80211_IFTYPE_P2P_CLIENT)
663 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 | BIT(NL80211_IFTYPE_AP);
665
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800667 if( pCfg->enableMCC )
668 {
669 /* Currently, supports up to two channels */
670 wlan_hdd_iface_combination.num_different_channels = 2;
671
672 if( !pCfg->allowMCCGODiffBI )
673 wlan_hdd_iface_combination.beacon_int_infra_match = true;
674
675 }
676 wiphy->iface_combinations = &wlan_hdd_iface_combination;
677 wiphy->n_iface_combinations = 1;
678#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800679
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 /* Before registering we need to update the ht capabilitied based
681 * on ini values*/
682 if( !pCfg->ShortGI20MhzEnable )
683 {
684 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
685 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
686 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
687 }
688
689 if( !pCfg->ShortGI40MhzEnable )
690 {
691 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
692 }
693
694 if( !pCfg->nChannelBondingMode5GHz )
695 {
696 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
697 }
698
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530699 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
700 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
701
702 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
703 {
704
705 if (NULL == wiphy->bands[i])
706 {
707 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
708 __func__, i);
709 continue;
710 }
711
712 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
713 {
714 struct ieee80211_supported_band *band = wiphy->bands[i];
715
716 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
717 {
718 // Enable social channels for P2P
719 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
720 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
721 else
722 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
723 continue;
724 }
725 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
726 {
727 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
728 continue;
729 }
730 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 }
732 /*Initialise the supported cipher suite details*/
733 wiphy->cipher_suites = hdd_cipher_suites;
734 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
735
736 /*signal strength in mBm (100*dBm) */
737 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
738
739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 wiphy->max_remain_on_channel_duration = 1000;
741#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700742
743 /* Register our wiphy dev with cfg80211 */
744 if (0 > wiphy_register(wiphy))
745 {
746 /* print eror */
747 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
748 return -EIO;
749 }
750
751 EXIT();
752 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530753}
Jeff Johnson295189b2012-06-20 16:38:30 -0700754
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700755/* In this function we will try to get default country code from crda.
756 If the gCrdaDefaultCountryCode is configured in ini file,
757 we will try to call user space crda to get the regulatory settings for
758 that country. We will timeout if we can't get it from crda.
759 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
760*/
761int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
762{
763 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
764 if (memcmp(pCfg->crdaDefaultCountryCode,
765 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
766 {
767 init_completion(&pHddCtx->driver_crda_req);
768 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
769 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
770 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700771 /* if the country is not found from current regulatory.bin,
772 fall back to world domain */
773 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
774 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700775 }
776 return 0;
777}
778
Jeff Johnson295189b2012-06-20 16:38:30 -0700779/* In this function we will do all post VOS start initialization.
780 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530781 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700782*/
783void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
784{
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
786 /* Register for all P2P action, public action etc frames */
787 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
788
Jeff Johnsone7245742012-09-05 17:12:55 -0700789 ENTER();
790
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 /* Right now we are registering these frame when driver is getting
792 initialized. Once we will move to 2.6.37 kernel, in which we have
793 frame register ops, we will move this code as a part of that */
794 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530795 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
797
798 /* GAS Initial Response */
799 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
800 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530801
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 /* GAS Comeback Request */
803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
804 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
805
806 /* GAS Comeback Response */
807 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
808 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
809
810 /* P2P Public Action */
811 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530812 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 P2P_PUBLIC_ACTION_FRAME_SIZE );
814
815 /* P2P Action */
816 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
817 (v_U8_t*)P2P_ACTION_FRAME,
818 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700819
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530820 /* WNM BSS Transition Request frame */
821 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
822 (v_U8_t*)WNM_BSS_ACTION_FRAME,
823 WNM_BSS_ACTION_FRAME_SIZE );
824
Chet Lanctot186b5732013-03-18 10:26:30 -0700825#ifdef WLAN_FEATURE_11W
826 /* SA Query Response Action Frame */
827 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
828 (v_U8_t*)SA_QUERY_FRAME_RSP,
829 SA_QUERY_FRAME_RSP_SIZE );
830#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700831}
832
833void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
834{
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
836 /* Register for all P2P action, public action etc frames */
837 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
838
Jeff Johnsone7245742012-09-05 17:12:55 -0700839 ENTER();
840
Jeff Johnson295189b2012-06-20 16:38:30 -0700841 /* Right now we are registering these frame when driver is getting
842 initialized. Once we will move to 2.6.37 kernel, in which we have
843 frame register ops, we will move this code as a part of that */
844 /* GAS Initial Request */
845
846 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
847 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
848
849 /* GAS Initial Response */
850 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
851 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530852
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 /* GAS Comeback Request */
854 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
855 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
856
857 /* GAS Comeback Response */
858 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
859 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
860
861 /* P2P Public Action */
862 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530863 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700864 P2P_PUBLIC_ACTION_FRAME_SIZE );
865
866 /* P2P Action */
867 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
868 (v_U8_t*)P2P_ACTION_FRAME,
869 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700870
871#ifdef WLAN_FEATURE_11W
872 /* SA Query Response Action Frame */
873 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
874 (v_U8_t*)SA_QUERY_FRAME_RSP,
875 SA_QUERY_FRAME_RSP_SIZE );
876#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700877}
878
879#ifdef FEATURE_WLAN_WAPI
880void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
881 const u8 *mac_addr, u8 *key , int key_Len)
882{
883 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
884 tCsrRoamSetKey setKey;
885 v_BOOL_t isConnected = TRUE;
886 int status = 0;
887 v_U32_t roamId= 0xFF;
888 tANI_U8 *pKeyPtr = NULL;
889 int n = 0;
890
891 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
892 __func__,pAdapter->device_mode);
893
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530894 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 setKey.keyId = key_index; // Store Key ID
896 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
897 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
898 setKey.paeRole = 0 ; // the PAE role
899 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
900 {
901 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
902 }
903 else
904 {
905 isConnected = hdd_connIsConnected(pHddStaCtx);
906 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
907 }
908 setKey.keyLength = key_Len;
909 pKeyPtr = setKey.Key;
910 memcpy( pKeyPtr, key, key_Len);
911
912 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
913 __func__, key_Len);
914 for (n = 0 ; n < key_Len; n++)
915 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
916 __func__,n,setKey.Key[n]);
917
918 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
919 if ( isConnected )
920 {
921 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
922 pAdapter->sessionId, &setKey, &roamId );
923 }
924 if ( status != 0 )
925 {
926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
927 "[%4d] sme_RoamSetKey returned ERROR status= %d",
928 __LINE__, status );
929 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
930 }
931}
932#endif /* FEATURE_WLAN_WAPI*/
933
934#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530935int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 beacon_data_t **ppBeacon,
937 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530939int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700940 beacon_data_t **ppBeacon,
941 struct cfg80211_beacon_data *params,
942 int dtim_period)
943#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944{
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 int size;
946 beacon_data_t *beacon = NULL;
947 beacon_data_t *old = NULL;
948 int head_len,tail_len;
949
Jeff Johnsone7245742012-09-05 17:12:55 -0700950 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 if (params->head && !params->head_len)
952 return -EINVAL;
953
954 old = pAdapter->sessionCtx.ap.beacon;
955
956 if (!params->head && !old)
957 return -EINVAL;
958
959 if (params->tail && !params->tail_len)
960 return -EINVAL;
961
962#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
963 /* Kernel 3.0 is not updating dtim_period for set beacon */
964 if (!params->dtim_period)
965 return -EINVAL;
966#endif
967
968 if(params->head)
969 head_len = params->head_len;
970 else
971 head_len = old->head_len;
972
973 if(params->tail || !old)
974 tail_len = params->tail_len;
975 else
976 tail_len = old->tail_len;
977
978 size = sizeof(beacon_data_t) + head_len + tail_len;
979
980 beacon = kzalloc(size, GFP_KERNEL);
981
982 if( beacon == NULL )
983 return -ENOMEM;
984
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700986 if(params->dtim_period || !old )
987 beacon->dtim_period = params->dtim_period;
988 else
989 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700990#else
991 if(dtim_period || !old )
992 beacon->dtim_period = dtim_period;
993 else
994 beacon->dtim_period = old->dtim_period;
995#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530996
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
998 beacon->tail = beacon->head + head_len;
999 beacon->head_len = head_len;
1000 beacon->tail_len = tail_len;
1001
1002 if(params->head) {
1003 memcpy (beacon->head,params->head,beacon->head_len);
1004 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301005 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 if(old)
1007 memcpy (beacon->head,old->head,beacon->head_len);
1008 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301009
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 if(params->tail) {
1011 memcpy (beacon->tail,params->tail,beacon->tail_len);
1012 }
1013 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301014 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 memcpy (beacon->tail,old->tail,beacon->tail_len);
1016 }
1017
1018 *ppBeacon = beacon;
1019
1020 kfree(old);
1021
1022 return 0;
1023
1024}
Jeff Johnson295189b2012-06-20 16:38:30 -07001025
1026v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1027{
1028 int left = length;
1029 v_U8_t *ptr = pIes;
1030 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301031
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301033 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 elem_id = ptr[0];
1035 elem_len = ptr[1];
1036 left -= 2;
1037 if(elem_len > left)
1038 {
1039 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001040 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 eid,elem_len,left);
1042 return NULL;
1043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301044 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 {
1046 return ptr;
1047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301048
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 left -= elem_len;
1050 ptr += (elem_len + 2);
1051 }
1052 return NULL;
1053}
1054
Jeff Johnson295189b2012-06-20 16:38:30 -07001055/* Check if rate is 11g rate or not */
1056static int wlan_hdd_rate_is_11g(u8 rate)
1057{
1058 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
1059 u8 i;
1060 for (i = 0; i < 8; i++)
1061 {
1062 if(rate == gRateArray[i])
1063 return TRUE;
1064 }
1065 return FALSE;
1066}
1067
1068/* Check for 11g rate and set proper 11g only mode */
1069static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1070 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1071{
1072 u8 i, num_rates = pIe[0];
1073
1074 pIe += 1;
1075 for ( i = 0; i < num_rates; i++)
1076 {
1077 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1078 {
1079 /* If rate set have 11g rate than change the mode to 11G */
1080 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1081 if (pIe[i] & BASIC_RATE_MASK)
1082 {
1083 /* If we have 11g rate as basic rate, it means mode
1084 is 11g only mode.
1085 */
1086 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1087 *pCheckRatesfor11g = FALSE;
1088 }
1089 }
1090 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1091 {
1092 *require_ht = TRUE;
1093 }
1094 }
1095 return;
1096}
1097
1098static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1099{
1100 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1101 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1102 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1103 u8 checkRatesfor11g = TRUE;
1104 u8 require_ht = FALSE;
1105 u8 *pIe=NULL;
1106
1107 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1108
1109 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1110 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1111 if (pIe != NULL)
1112 {
1113 pIe += 1;
1114 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1115 &pConfig->SapHw_mode);
1116 }
1117
1118 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1119 WLAN_EID_EXT_SUPP_RATES);
1120 if (pIe != NULL)
1121 {
1122
1123 pIe += 1;
1124 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1125 &pConfig->SapHw_mode);
1126 }
1127
1128 if( pConfig->channel > 14 )
1129 {
1130 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1131 }
1132
1133 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1134 WLAN_EID_HT_CAPABILITY);
1135
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301136 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 {
1138 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1139 if(require_ht)
1140 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1141 }
1142}
1143
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301144static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1145 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1146{
1147 v_U8_t ielen = 0;
1148 v_U8_t *pIe = NULL;
1149 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1150
1151 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1152 pBeacon->tail, pBeacon->tail_len);
1153
1154 if (pIe)
1155 {
1156 ielen = pIe[1] + 2;
1157 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1158 {
1159 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1160 }
1161 else
1162 {
1163 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1164 return -EINVAL;
1165 }
1166 *total_ielen += ielen;
1167 }
1168 return 0;
1169}
1170
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001171#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001172static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1173 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001174#else
1175static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1176 struct cfg80211_beacon_data *params)
1177#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001178{
1179 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301180 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001182 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001183
1184 genie = vos_mem_malloc(MAX_GENIE_LEN);
1185
1186 if(genie == NULL) {
1187
1188 return -ENOMEM;
1189 }
1190
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301191 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1192 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301194 ret = -EINVAL;
1195 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 }
1197
1198#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301199 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1200 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1201 {
1202 ret = -EINVAL;
1203 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 }
1205#endif
1206
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301207 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1208 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301210 ret = -EINVAL;
1211 goto done;
1212 }
1213
1214 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1215 {
1216 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1217 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301219 ret = -EINVAL;
1220 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001223
1224 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1225 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1226 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1227 {
1228 hddLog(LOGE,
1229 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001230 ret = -EINVAL;
1231 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 }
1233
1234 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1235 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1236 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1237 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1238 ==eHAL_STATUS_FAILURE)
1239 {
1240 hddLog(LOGE,
1241 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001242 ret = -EINVAL;
1243 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001244 }
1245
1246 // Added for ProResp IE
1247 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1248 {
1249 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1250 u8 probe_rsp_ie_len[3] = {0};
1251 u8 counter = 0;
1252 /* Check Probe Resp Length if it is greater then 255 then Store
1253 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1254 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1255 Store More then 255 bytes into One Variable.
1256 */
1257 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1258 {
1259 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1260 {
1261 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1262 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1263 }
1264 else
1265 {
1266 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1267 rem_probe_resp_ie_len = 0;
1268 }
1269 }
1270
1271 rem_probe_resp_ie_len = 0;
1272
1273 if (probe_rsp_ie_len[0] > 0)
1274 {
1275 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1276 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1277 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1278 probe_rsp_ie_len[0], NULL,
1279 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1280 {
1281 hddLog(LOGE,
1282 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001283 ret = -EINVAL;
1284 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 }
1286 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1287 }
1288
1289 if (probe_rsp_ie_len[1] > 0)
1290 {
1291 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1292 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1293 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1294 probe_rsp_ie_len[1], NULL,
1295 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1296 {
1297 hddLog(LOGE,
1298 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001299 ret = -EINVAL;
1300 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 }
1302 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1303 }
1304
1305 if (probe_rsp_ie_len[2] > 0)
1306 {
1307 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1308 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1309 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1310 probe_rsp_ie_len[2], NULL,
1311 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1312 {
1313 hddLog(LOGE,
1314 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001315 ret = -EINVAL;
1316 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 }
1318 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1319 }
1320
1321 if (probe_rsp_ie_len[1] == 0 )
1322 {
1323 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1324 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1325 eANI_BOOLEAN_FALSE) )
1326 {
1327 hddLog(LOGE,
1328 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1329 }
1330 }
1331
1332 if (probe_rsp_ie_len[2] == 0 )
1333 {
1334 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1335 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1336 eANI_BOOLEAN_FALSE) )
1337 {
1338 hddLog(LOGE,
1339 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1340 }
1341 }
1342
1343 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1344 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1345 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1346 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1347 == eHAL_STATUS_FAILURE)
1348 {
1349 hddLog(LOGE,
1350 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001351 ret = -EINVAL;
1352 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 }
1354 }
1355 else
1356 {
1357 // Reset WNI_CFG_PROBE_RSP Flags
1358 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1359
1360 hddLog(VOS_TRACE_LEVEL_INFO,
1361 "%s: No Probe Response IE received in set beacon",
1362 __func__);
1363 }
1364
1365 // Added for AssocResp IE
1366 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1367 {
1368 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1369 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1370 params->assocresp_ies_len, NULL,
1371 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1372 {
1373 hddLog(LOGE,
1374 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001375 ret = -EINVAL;
1376 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 }
1378
1379 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1380 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1381 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1382 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1383 == eHAL_STATUS_FAILURE)
1384 {
1385 hddLog(LOGE,
1386 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001387 ret = -EINVAL;
1388 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001389 }
1390 }
1391 else
1392 {
1393 hddLog(VOS_TRACE_LEVEL_INFO,
1394 "%s: No Assoc Response IE received in set beacon",
1395 __func__);
1396
1397 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1398 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1399 eANI_BOOLEAN_FALSE) )
1400 {
1401 hddLog(LOGE,
1402 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1403 }
1404 }
1405
Jeff Johnsone7245742012-09-05 17:12:55 -07001406done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301408 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001409}
Jeff Johnson295189b2012-06-20 16:38:30 -07001410
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301411/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 * FUNCTION: wlan_hdd_validate_operation_channel
1413 * called by wlan_hdd_cfg80211_start_bss() and
1414 * wlan_hdd_cfg80211_set_channel()
1415 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301416 * channel list.
1417 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001418VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001419{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 v_U32_t num_ch = 0;
1422 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1423 u32 indx = 0;
1424 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301425 v_U8_t fValidChannel = FALSE, count = 0;
1426 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301427
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1429
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301430 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301432 /* Validate the channel */
1433 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001434 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301435 if ( channel == rfChannels[count].channelNum )
1436 {
1437 fValidChannel = TRUE;
1438 break;
1439 }
1440 }
1441 if (fValidChannel != TRUE)
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 "%s: Invalid Channel [%d]", __func__, channel);
1445 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 }
1447 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301448 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301450 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1451 valid_ch, &num_ch))
1452 {
1453 hddLog(VOS_TRACE_LEVEL_ERROR,
1454 "%s: failed to get valid channel list", __func__);
1455 return VOS_STATUS_E_FAILURE;
1456 }
1457 for (indx = 0; indx < num_ch; indx++)
1458 {
1459 if (channel == valid_ch[indx])
1460 {
1461 break;
1462 }
1463 }
1464
1465 if (indx >= num_ch)
1466 {
1467 hddLog(VOS_TRACE_LEVEL_ERROR,
1468 "%s: Invalid Channel [%d]", __func__, channel);
1469 return VOS_STATUS_E_FAILURE;
1470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 }
1472 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301473
Jeff Johnson295189b2012-06-20 16:38:30 -07001474}
1475
Viral Modi3a32cc52013-02-08 11:14:52 -08001476/**
1477 * FUNCTION: wlan_hdd_cfg80211_set_channel
1478 * This function is used to set the channel number
1479 */
1480static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1481 struct ieee80211_channel *chan,
1482 enum nl80211_channel_type channel_type
1483 )
1484{
1485 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001486 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001487 hdd_adapter_t *pAdapter = NULL;
1488 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301489 hdd_context_t *pHddCtx;
1490 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001491
1492 ENTER();
1493
1494 if( NULL == dev )
1495 {
1496 hddLog(VOS_TRACE_LEVEL_ERROR,
1497 "%s: Called with dev = NULL.\n", __func__);
1498 return -ENODEV;
1499 }
1500 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1501
1502 hddLog(VOS_TRACE_LEVEL_INFO,
1503 "%s: device_mode = %d freq = %d \n",__func__,
1504 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301505
1506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1507 status = wlan_hdd_validate_context(pHddCtx);
1508
1509 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1512 "%s: HDD context is not valid", __func__);
1513 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001514 }
1515
1516 /*
1517 * Do freq to chan conversion
1518 * TODO: for 11a
1519 */
1520
1521 channel = ieee80211_frequency_to_channel(freq);
1522
1523 /* Check freq range */
1524 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1525 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1526 {
1527 hddLog(VOS_TRACE_LEVEL_ERROR,
1528 "%s: Channel [%d] is outside valid range from %d to %d\n",
1529 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1530 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1531 return -EINVAL;
1532 }
1533
1534 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1535
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301536 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1537 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001538 {
1539 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 "%s: Invalid Channel [%d] \n", __func__, channel);
1543 return -EINVAL;
1544 }
1545 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1546 "%s: set channel to [%d] for device mode =%d",
1547 __func__, channel,pAdapter->device_mode);
1548 }
1549 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001550 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001551 )
1552 {
1553 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1554 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1555 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1556
1557 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1558 {
1559 /* Link is up then return cant set channel*/
1560 hddLog( VOS_TRACE_LEVEL_ERROR,
1561 "%s: IBSS Associated, can't set the channel\n", __func__);
1562 return -EINVAL;
1563 }
1564
1565 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1566 pHddStaCtx->conn_info.operationChannel = channel;
1567 pRoamProfile->ChannelInfo.ChannelList =
1568 &pHddStaCtx->conn_info.operationChannel;
1569 }
1570 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001571 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001572 )
1573 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301574 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1575 {
1576 if(VOS_STATUS_SUCCESS !=
1577 wlan_hdd_validate_operation_channel(pAdapter,channel))
1578 {
1579 hddLog(VOS_TRACE_LEVEL_ERROR,
1580 "%s: Invalid Channel [%d] \n", __func__, channel);
1581 return -EINVAL;
1582 }
1583 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1584 }
1585 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001586 {
1587 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1588
1589 /* If auto channel selection is configured as enable/ 1 then ignore
1590 channel set by supplicant
1591 */
1592 if ( cfg_param->apAutoChannelSelection )
1593 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301594 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1595 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001596 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1597 "%s: set channel to auto channel (0) for device mode =%d",
1598 __func__, pAdapter->device_mode);
1599 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301600 else
1601 {
1602 if(VOS_STATUS_SUCCESS !=
1603 wlan_hdd_validate_operation_channel(pAdapter,channel))
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 "%s: Invalid Channel [%d] \n", __func__, channel);
1607 return -EINVAL;
1608 }
1609 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1610 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001611 }
1612 }
1613 else
1614 {
1615 hddLog(VOS_TRACE_LEVEL_FATAL,
1616 "%s: Invalid device mode failed to set valid channel", __func__);
1617 return -EINVAL;
1618 }
1619 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301620 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001621}
1622
Jeff Johnson295189b2012-06-20 16:38:30 -07001623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1624static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1625 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001626#else
1627static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1628 struct cfg80211_beacon_data *params,
1629 const u8 *ssid, size_t ssid_len,
1630 enum nl80211_hidden_ssid hidden_ssid)
1631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001632{
1633 tsap_Config_t *pConfig;
1634 beacon_data_t *pBeacon = NULL;
1635 struct ieee80211_mgmt *pMgmt_frame;
1636 v_U8_t *pIe=NULL;
1637 v_U16_t capab_info;
1638 eCsrAuthType RSNAuthType;
1639 eCsrEncryptionType RSNEncryptType;
1640 eCsrEncryptionType mcRSNEncryptType;
1641 int status = VOS_STATUS_SUCCESS;
1642 tpWLAN_SAPEventCB pSapEventCallback;
1643 hdd_hostapd_state_t *pHostapdState;
1644 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1645 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 struct qc_mac_acl_entry *acl_entry = NULL;
1648 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650
1651 ENTER();
1652
1653 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1654
1655 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1656
1657 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1658
1659 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1660
1661 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1662
1663 //channel is already set in the set_channel Call back
1664 //pConfig->channel = pCommitConfig->channel;
1665
1666 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301667 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1669
1670 pConfig->dtim_period = pBeacon->dtim_period;
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1673 pConfig->dtim_period);
1674
1675
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001676 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001677 {
1678 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001680 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001682 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001683 pConfig->ieee80211d = 1;
1684 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1685 sme_setRegInfo(hHal, pConfig->countryCode);
1686 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001688 else
1689 {
1690 pConfig->ieee80211d = 0;
1691 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301692 /*
1693 * If auto channel is configured i.e. channel is 0,
1694 * so skip channel validation.
1695 */
1696 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1697 {
1698 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1699 {
1700 hddLog(VOS_TRACE_LEVEL_ERROR,
1701 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1702 return -EINVAL;
1703 }
1704 }
1705 else
1706 {
1707 if(1 != pHddCtx->is_dynamic_channel_range_set)
1708 {
1709 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1710 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1711 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1712 }
1713 pHddCtx->is_dynamic_channel_range_set = 0;
1714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001716 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 {
1718 pConfig->ieee80211d = 0;
1719 }
1720 pConfig->authType = eSAP_AUTO_SWITCH;
1721
1722 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301723
1724 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1726
1727 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1728
1729 /*Set wps station to configured*/
1730 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1731
1732 if(pIe)
1733 {
1734 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1735 {
1736 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1737 return -EINVAL;
1738 }
1739 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1740 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001741 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 /* Check 15 bit of WPS IE as it contain information for wps state
1743 * WPS state
1744 */
1745 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1746 {
1747 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1748 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1749 {
1750 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1751 }
1752 }
1753 }
1754 else
1755 {
1756 pConfig->wps_state = SAP_WPS_DISABLED;
1757 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301758 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001759
1760 pConfig->RSNWPAReqIELength = 0;
1761 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301762 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 WLAN_EID_RSN);
1764 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301765 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1767 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1768 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301769 /* The actual processing may eventually be more extensive than
1770 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 * by the app.
1772 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301773 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1775 &RSNEncryptType,
1776 &mcRSNEncryptType,
1777 &RSNAuthType,
1778 pConfig->pRSNWPAReqIE[1]+2,
1779 pConfig->pRSNWPAReqIE );
1780
1781 if( VOS_STATUS_SUCCESS == status )
1782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301783 /* Now copy over all the security attributes you have
1784 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 * */
1786 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1787 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1788 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1789 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301790 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 "EncryptionType = %d mcEncryptionType = %d\n"),
1792 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1793 }
1794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301795
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1797 pBeacon->tail, pBeacon->tail_len);
1798
1799 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1800 {
1801 if (pConfig->pRSNWPAReqIE)
1802 {
1803 /*Mixed mode WPA/WPA2*/
1804 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1805 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1806 }
1807 else
1808 {
1809 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1810 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1811 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301812 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1814 &RSNEncryptType,
1815 &mcRSNEncryptType,
1816 &RSNAuthType,
1817 pConfig->pRSNWPAReqIE[1]+2,
1818 pConfig->pRSNWPAReqIE );
1819
1820 if( VOS_STATUS_SUCCESS == status )
1821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301822 /* Now copy over all the security attributes you have
1823 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 * */
1825 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1826 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1827 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1828 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301829 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 "EncryptionType = %d mcEncryptionType = %d\n"),
1831 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1832 }
1833 }
1834 }
1835
Jeff Johnson4416a782013-03-25 14:17:50 -07001836 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1837 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1838 return -EINVAL;
1839 }
1840
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1842
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 if (params->ssid != NULL)
1845 {
1846 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1847 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1848 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1849 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1850 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001851#else
1852 if (ssid != NULL)
1853 {
1854 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1855 pConfig->SSIDinfo.ssid.length = ssid_len;
1856 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1857 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1858 }
1859#endif
1860
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301861 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301863
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 /* default value */
1865 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1866 pConfig->num_accept_mac = 0;
1867 pConfig->num_deny_mac = 0;
1868
1869 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1870 pBeacon->tail, pBeacon->tail_len);
1871
1872 /* pIe for black list is following form:
1873 type : 1 byte
1874 length : 1 byte
1875 OUI : 4 bytes
1876 acl type : 1 byte
1877 no of mac addr in black list: 1 byte
1878 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301879 */
1880 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 {
1882 pConfig->SapMacaddr_acl = pIe[6];
1883 pConfig->num_deny_mac = pIe[7];
1884 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1885 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301886 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1887 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1889 for (i = 0; i < pConfig->num_deny_mac; i++)
1890 {
1891 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1892 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 }
1895 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1896 pBeacon->tail, pBeacon->tail_len);
1897
1898 /* pIe for white list is following form:
1899 type : 1 byte
1900 length : 1 byte
1901 OUI : 4 bytes
1902 acl type : 1 byte
1903 no of mac addr in white list: 1 byte
1904 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301905 */
1906 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 {
1908 pConfig->SapMacaddr_acl = pIe[6];
1909 pConfig->num_accept_mac = pIe[7];
1910 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1911 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301912 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1913 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1915 for (i = 0; i < pConfig->num_accept_mac; i++)
1916 {
1917 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1918 acl_entry++;
1919 }
1920 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1923
Jeff Johnsone7245742012-09-05 17:12:55 -07001924#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001925 /* Overwrite the hostapd setting for HW mode only for 11ac.
1926 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1927 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1928 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1929 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301930 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001931 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1932 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001933 {
1934 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07001935
1936 /* Disable VHT support in 2.4 GHz band */
1937 if (pConfig->channel <= 14 &&
1938 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
1939 {
1940 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1941 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001942 }
1943#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301944
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001945 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1946 {
1947 sme_SelectCBMode(hHal,
1948 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1949 pConfig->channel);
1950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 // ht_capab is not what the name conveys,this is used for protection bitmap
1952 pConfig->ht_capab =
1953 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1954
1955 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1956 {
1957 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1958 return -EINVAL;
1959 }
1960
1961 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301962 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1964 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301965 pConfig->obssProtEnabled =
1966 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001967
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301968 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301970 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1972 (int)pConfig->channel);
1973 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301974 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1975 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301977 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1979 pConfig->protEnabled, pConfig->obssProtEnabled);
1980
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301981 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 {
1983 //Bss already started. just return.
1984 //TODO Probably it should update some beacon params.
1985 hddLog( LOGE, "Bss Already started...Ignore the request");
1986 EXIT();
1987 return 0;
1988 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 pConfig->persona = pHostapdAdapter->device_mode;
1991
1992 pSapEventCallback = hdd_hostapd_SAPEventCB;
1993 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1994 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1995 {
1996 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1997 return -EINVAL;
1998 }
1999
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302000 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2002
2003 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302004
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302006 {
2007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 ("ERROR: HDD vos wait for single_event failed!!\n"));
2009 VOS_ASSERT(0);
2010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302011
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 //Succesfully started Bss update the state bit.
2013 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2014
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002015#ifdef WLAN_FEATURE_P2P_DEBUG
2016 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2017 {
2018 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2019 {
2020 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2021 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002022 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002023 }
2024 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2025 {
2026 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2027 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002028 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002029 }
2030 }
2031#endif
2032
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 pHostapdState->bCommit = TRUE;
2034 EXIT();
2035
2036 return 0;
2037}
2038
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002039#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302040static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2041 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 struct beacon_parameters *params)
2043{
2044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302045 hdd_context_t *pHddCtx;
2046 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002047
2048 ENTER();
2049
2050 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2051
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302052 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2053 status = wlan_hdd_validate_context(pHddCtx);
2054
2055 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2058 "%s: HDD context is not valid", __func__);
2059 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002060 }
2061
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302062 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 )
2065 {
2066 beacon_data_t *old,*new;
2067
2068 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302069
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 if (old)
2071 return -EALREADY;
2072
2073 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2074
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302075 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 {
2077 hddLog(VOS_TRACE_LEVEL_FATAL,
2078 "%s:Error!!! Allocating the new beacon\n",__func__);
2079 return -EINVAL;
2080 }
2081
2082 pAdapter->sessionCtx.ap.beacon = new;
2083
2084 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2085 }
2086
2087 EXIT();
2088 return status;
2089}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302090
2091static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002092 struct net_device *dev,
2093 struct beacon_parameters *params)
2094{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302096 hdd_context_t *pHddCtx;
2097 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002098
2099 ENTER();
2100
2101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2102 __func__,pAdapter->device_mode);
2103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2105 status = wlan_hdd_validate_context(pHddCtx);
2106
2107 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2110 "%s: HDD context is not valid", __func__);
2111 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002112 }
2113
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302116 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 {
2118 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302119
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302121
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 if (!old)
2123 return -ENOENT;
2124
2125 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2126
2127 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302128 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 "%s: Error!!! Allocating the new beacon\n",__func__);
2130 return -EINVAL;
2131 }
2132
2133 pAdapter->sessionCtx.ap.beacon = new;
2134
2135 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2136 }
2137
2138 EXIT();
2139 return status;
2140}
2141
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002142#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2143
2144#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002145static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2146 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002147#else
2148static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2149 struct net_device *dev)
2150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002151{
2152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002153 hdd_context_t *pHddCtx = NULL;
2154 hdd_scaninfo_t *pScanInfo = NULL;
2155 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302156 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
2158 ENTER();
2159
2160 if (NULL == pAdapter)
2161 {
2162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002163 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 return -ENODEV;
2165 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002166
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2168 status = wlan_hdd_validate_context(pHddCtx);
2169
2170 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2173 "%s: HDD context is not valid", __func__);
2174 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002175 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002176
2177 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2178 if (NULL == staAdapter)
2179 {
2180 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2181 if (NULL == staAdapter)
2182 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002184 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002185 return -ENODEV;
2186 }
2187 }
2188
2189 pScanInfo = &pHddCtx->scan_info;
2190
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2192 __func__,pAdapter->device_mode);
2193
Jeff Johnsone7245742012-09-05 17:12:55 -07002194 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2195 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002196 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002197 hdd_abort_mac_scan(staAdapter->pHddCtx);
2198 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002199 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2201 if (!status)
2202 {
2203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002204 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002205 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002206 VOS_ASSERT(pScanInfo->mScanPending);
2207 return 0;
2208 }
2209 }
2210
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002213 )
2214 {
2215 beacon_data_t *old;
2216
2217 old = pAdapter->sessionCtx.ap.beacon;
2218
2219 if (!old)
2220 return -ENOENT;
2221
Jeff Johnson295189b2012-06-20 16:38:30 -07002222 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002223
2224 mutex_lock(&pHddCtx->sap_lock);
2225 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2226 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002227 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 {
2229 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2230
2231 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2232
2233 if (!VOS_IS_STATUS_SUCCESS(status))
2234 {
2235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2236 ("ERROR: HDD vos wait for single_event failed!!\n"));
2237 VOS_ASSERT(0);
2238 }
2239 }
2240 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2241 }
2242 mutex_unlock(&pHddCtx->sap_lock);
2243
2244 if(status != VOS_STATUS_SUCCESS)
2245 {
2246 hddLog(VOS_TRACE_LEVEL_FATAL,
2247 "%s:Error!!! Stopping the BSS\n",__func__);
2248 return -EINVAL;
2249 }
2250
Jeff Johnson4416a782013-03-25 14:17:50 -07002251 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2253 ==eHAL_STATUS_FAILURE)
2254 {
2255 hddLog(LOGE,
2256 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2257 }
2258
Jeff Johnson4416a782013-03-25 14:17:50 -07002259 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2261 eANI_BOOLEAN_FALSE) )
2262 {
2263 hddLog(LOGE,
2264 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2265 }
2266
2267 // Reset WNI_CFG_PROBE_RSP Flags
2268 wlan_hdd_reset_prob_rspies(pAdapter);
2269
2270 pAdapter->sessionCtx.ap.beacon = NULL;
2271 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002272#ifdef WLAN_FEATURE_P2P_DEBUG
2273 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2274 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2275 {
2276 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2277 "GO got removed");
2278 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2279 }
2280#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 }
2282 EXIT();
2283 return status;
2284}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002285
2286#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2287
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302288static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2289 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002290 struct cfg80211_ap_settings *params)
2291{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302292 hdd_adapter_t *pAdapter;
2293 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302294 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002295
2296 ENTER();
2297
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 "%s: Device is Null", __func__);
2302 return -ENODEV;
2303 }
2304
2305 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2306 if (NULL == pAdapter)
2307 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302309 "%s: HDD adapter is Null", __func__);
2310 return -ENODEV;
2311 }
2312
2313 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2314 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302316 "%s: HDD adapter magic is invalid", __func__);
2317 return -ENODEV;
2318 }
2319
2320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302321 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302322
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302323 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302324 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2326 "%s: HDD context is not valid", __func__);
2327 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302328 }
2329
2330 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2331 __func__, pAdapter->device_mode);
2332
2333 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002334 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002335 )
2336 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302337 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002338
2339 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302340
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002341 if (old)
2342 return -EALREADY;
2343
2344 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2345
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302346 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002347 {
2348 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302349 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002350 return -EINVAL;
2351 }
2352 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2354 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2355#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002356 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2357 params->ssid_len, params->hidden_ssid);
2358 }
2359
2360 EXIT();
2361 return status;
2362}
2363
2364
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302365static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002366 struct net_device *dev,
2367 struct cfg80211_beacon_data *params)
2368{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302370 hdd_context_t *pHddCtx;
2371 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002372
2373 ENTER();
2374
2375 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2376 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302377
2378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2379 status = wlan_hdd_validate_context(pHddCtx);
2380
2381 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002382 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2384 "%s: HDD context is not valid", __func__);
2385 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002386 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002387
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302388 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302390 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002391 {
2392 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302393
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002394 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302395
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396 if (!old)
2397 return -ENOENT;
2398
2399 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2400
2401 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302402 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002403 "%s: Error!!! Allocating the new beacon\n",__func__);
2404 return -EINVAL;
2405 }
2406
2407 pAdapter->sessionCtx.ap.beacon = new;
2408
2409 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2410 }
2411
2412 EXIT();
2413 return status;
2414}
2415
2416#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2417
Jeff Johnson295189b2012-06-20 16:38:30 -07002418
2419static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2420 struct net_device *dev,
2421 struct bss_parameters *params)
2422{
2423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2424
2425 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302426
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2428 __func__,pAdapter->device_mode);
2429
2430 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302432 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002433 {
2434 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2435 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 {
2438 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 }
2441
2442 EXIT();
2443 return 0;
2444}
2445
2446/*
2447 * FUNCTION: wlan_hdd_cfg80211_change_iface
2448 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2449 */
2450int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2451 struct net_device *ndev,
2452 enum nl80211_iftype type,
2453 u32 *flags,
2454 struct vif_params *params
2455 )
2456{
2457 struct wireless_dev *wdev;
2458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2459 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002460 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 tCsrRoamProfile *pRoamProfile = NULL;
2462 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302463 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002464 eMib_dot11DesiredBssType connectedBssType;
2465 VOS_STATUS status;
2466
2467 ENTER();
2468
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302469 status = wlan_hdd_validate_context(pHddCtx);
2470
2471 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002472 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "%s: HDD context is not valid", __func__);
2475 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 }
2477
2478 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2479 __func__, pAdapter->device_mode);
2480
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302481 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 wdev = ndev->ieee80211_ptr;
2483
2484#ifdef WLAN_BTAMP_FEATURE
2485 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2486 (NL80211_IFTYPE_ADHOC == type)||
2487 (NL80211_IFTYPE_AP == type)||
2488 (NL80211_IFTYPE_P2P_GO == type))
2489 {
2490 pHddCtx->isAmpAllowed = VOS_FALSE;
2491 // stop AMP traffic
2492 status = WLANBAP_StopAmp();
2493 if(VOS_STATUS_SUCCESS != status )
2494 {
2495 pHddCtx->isAmpAllowed = VOS_TRUE;
2496 hddLog(VOS_TRACE_LEVEL_FATAL,
2497 "%s: Failed to stop AMP", __func__);
2498 return -EINVAL;
2499 }
2500 }
2501#endif //WLAN_BTAMP_FEATURE
2502 /* Reset the current device mode bit mask*/
2503 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2504
2505 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002507 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002508 )
2509 {
2510 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2511 pRoamProfile = &pWextState->roamProfile;
2512 LastBSSType = pRoamProfile->BSSType;
2513
2514 switch (type)
2515 {
2516 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 hddLog(VOS_TRACE_LEVEL_INFO,
2519 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2520 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002521#ifdef WLAN_FEATURE_11AC
2522 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2523 {
2524 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2525 }
2526#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302527 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002528 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002530 //Check for sub-string p2p to confirm its a p2p interface
2531 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302532 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002533 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2534 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2535 }
2536 else
2537 {
2538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002539 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 break;
2542 case NL80211_IFTYPE_ADHOC:
2543 hddLog(VOS_TRACE_LEVEL_INFO,
2544 "%s: setting interface Type to ADHOC", __func__);
2545 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2546 pRoamProfile->phyMode =
2547 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002548 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 wdev->iftype = type;
2550 break;
2551
2552 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 {
2555 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2556 "%s: setting interface Type to %s", __func__,
2557 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2558
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002559 //Cancel any remain on channel for GO mode
2560 if (NL80211_IFTYPE_P2P_GO == type)
2561 {
2562 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2563 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002564 if (NL80211_IFTYPE_AP == type)
2565 {
2566 /* As Loading WLAN Driver one interface being created for p2p device
2567 * address. This will take one HW STA and the max number of clients
2568 * that can connect to softAP will be reduced by one. so while changing
2569 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2570 * interface as it is not required in SoftAP mode.
2571 */
2572
2573 // Get P2P Adapter
2574 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2575
2576 if (pP2pAdapter)
2577 {
2578 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2579 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2580 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2581 }
2582 }
2583
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 //De-init the adapter.
2585 hdd_stop_adapter( pHddCtx, pAdapter );
2586 hdd_deinit_adapter( pHddCtx, pAdapter );
2587 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2589 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002590
2591 //Disable BMPS and IMPS if enabled
2592 //before starting Go
2593 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302595 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002596 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2597 {
2598 //Fail to Exit BMPS
2599 VOS_ASSERT(0);
2600 }
2601 }
2602
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002603 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2604 (pConfig->apRandomBssidEnabled))
2605 {
2606 /* To meet Android requirements create a randomized
2607 MAC address of the form 02:1A:11:Fx:xx:xx */
2608 get_random_bytes(&ndev->dev_addr[3], 3);
2609 ndev->dev_addr[0] = 0x02;
2610 ndev->dev_addr[1] = 0x1A;
2611 ndev->dev_addr[2] = 0x11;
2612 ndev->dev_addr[3] |= 0xF0;
2613 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2614 VOS_MAC_ADDR_SIZE);
2615 pr_info("wlan: Generated HotSpot BSSID "
2616 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2617 ndev->dev_addr[0],
2618 ndev->dev_addr[1],
2619 ndev->dev_addr[2],
2620 ndev->dev_addr[3],
2621 ndev->dev_addr[4],
2622 ndev->dev_addr[5]);
2623 }
2624
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 hdd_set_ap_ops( pAdapter->dev );
2626
2627 status = hdd_init_ap_mode(pAdapter);
2628 if(status != VOS_STATUS_SUCCESS)
2629 {
2630 hddLog(VOS_TRACE_LEVEL_FATAL,
2631 "%s: Error initializing the ap mode", __func__);
2632 return -EINVAL;
2633 }
2634 hdd_set_conparam(1);
2635
Jeff Johnson295189b2012-06-20 16:38:30 -07002636 /*interface type changed update in wiphy structure*/
2637 if(wdev)
2638 {
2639 wdev->iftype = type;
2640 pHddCtx->change_iface = type;
2641 }
2642 else
2643 {
2644 hddLog(VOS_TRACE_LEVEL_ERROR,
2645 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2646 return -EINVAL;
2647 }
2648 goto done;
2649 }
2650
2651 default:
2652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2653 __func__);
2654 return -EOPNOTSUPP;
2655 }
2656 }
2657 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002659 )
2660 {
2661 switch(type)
2662 {
2663 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002664 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002665 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002666 hdd_stop_adapter( pHddCtx, pAdapter );
2667 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002669 //Check for sub-string p2p to confirm its a p2p interface
2670 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002671 {
2672 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2673 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2674 }
2675 else
2676 {
2677 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002678 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 hdd_set_conparam(0);
2681 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2683 hdd_set_station_ops( pAdapter->dev );
2684 status = hdd_init_station_mode( pAdapter );
2685 if( VOS_STATUS_SUCCESS != status )
2686 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002687 /* In case of JB, for P2P-GO, only change interface will be called,
2688 * This is the right place to enable back bmps_imps()
2689 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302690 if (pHddCtx->hdd_wlan_suspended)
2691 {
2692 hdd_set_pwrparams(pHddCtx);
2693 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002694 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 goto done;
2696 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002698 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2700 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002701 goto done;
2702 default:
2703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2704 __func__);
2705 return -EOPNOTSUPP;
2706
2707 }
2708
2709 }
2710 else
2711 {
2712 return -EOPNOTSUPP;
2713 }
2714
2715
2716 if(pRoamProfile)
2717 {
2718 if ( LastBSSType != pRoamProfile->BSSType )
2719 {
2720 /*interface type changed update in wiphy structure*/
2721 wdev->iftype = type;
2722
2723 /*the BSS mode changed, We need to issue disconnect
2724 if connected or in IBSS disconnect state*/
2725 if ( hdd_connGetConnectedBssType(
2726 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2727 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2728 {
2729 /*need to issue a disconnect to CSR.*/
2730 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2731 if( eHAL_STATUS_SUCCESS ==
2732 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2733 pAdapter->sessionId,
2734 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2735 {
2736 wait_for_completion_interruptible_timeout(
2737 &pAdapter->disconnect_comp_var,
2738 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2739 }
2740 }
2741 }
2742 }
2743
2744done:
2745 /*set bitmask based on updated value*/
2746 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2747#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302748 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2750 {
2751 //we are ok to do AMP
2752 pHddCtx->isAmpAllowed = VOS_TRUE;
2753 }
2754#endif //WLAN_BTAMP_FEATURE
2755 EXIT();
2756 return 0;
2757}
2758
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002759#ifdef FEATURE_WLAN_TDLS
2760static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2761 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2762{
2763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2765 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002766 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002767
2768 ENTER();
2769
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302770 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002771 {
2772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "Invalid arguments");
2774 return -EINVAL;
2775 }
Hoonki Lee27511902013-03-14 18:19:06 -07002776
2777 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2778 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2781 "%s: TDLS mode is disabled OR not enabled in FW."
2782 MAC_ADDRESS_STR " Request declined.",
2783 __func__, MAC_ADDR_ARRAY(mac));
2784 return -ENOTSUPP;
2785 }
2786
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002787 if (pHddCtx->isLogpInProgress)
2788 {
2789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002791 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002792 return -EBUSY;
2793 }
2794
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002795 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2796
2797 if ( NULL == pTdlsPeer ) {
2798 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2799 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2800 __func__, MAC_ADDR_ARRAY(mac), update);
2801 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002802 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002803
2804 /* in add station, we accept existing valid staId if there is */
2805 if ((0 == update) &&
2806 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2807 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002808 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002809 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002810 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002811 " link_status %d. staId %d. add station ignored.",
2812 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2813 return 0;
2814 }
2815 /* in change station, we accept only when staId is valid */
2816 if ((1 == update) &&
2817 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2818 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2819 {
2820 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2821 "%s: " MAC_ADDRESS_STR
2822 " link status %d. staId %d. change station %s.",
2823 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2824 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2825 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002826 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002827
2828 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002829 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002830 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "%s: " MAC_ADDRESS_STR
2833 " TDLS setup is ongoing. Request declined.",
2834 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002835 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002836 }
2837
2838 /* first to check if we reached to maximum supported TDLS peer.
2839 TODO: for now, return -EPERM looks working fine,
2840 but need to check if any other errno fit into this category.*/
2841 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2842 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2844 "%s: " MAC_ADDRESS_STR
2845 " TDLS Max peer already connected. Request declined.",
2846 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002847 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848 }
2849 else
2850 {
2851 hddTdlsPeer_t *pTdlsPeer;
2852 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002853 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002854 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2857 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002858 return -EPERM;
2859 }
2860 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002861 if (0 == update)
2862 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002863
Jeff Johnsond75fe012013-04-06 10:53:06 -07002864 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302865 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002866 {
2867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2868 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002869 if(StaParams->htcap_present)
2870 {
2871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2872 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2873 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2874 "ht_capa->extended_capabilities: %0x",
2875 StaParams->HTCap.extendedHtCapInfo);
2876 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002877 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2878 "params->capability: %0x",StaParams->capability);
2879 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2880 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002881 if(StaParams->vhtcap_present)
2882 {
2883 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2884 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2885 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2886 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2887 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002888 {
2889 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002891 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2892 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2893 "[%d]: %x ", i, StaParams->supported_rates[i]);
2894 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002895 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302896 else if ((1 == update) && (NULL == StaParams))
2897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "%s : update is true, but staParams is NULL. Error!", __func__);
2900 return -EPERM;
2901 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002902
2903 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2904
2905 if (!update)
2906 {
2907 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2908 pAdapter->sessionId, mac);
2909 }
2910 else
2911 {
2912 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2913 pAdapter->sessionId, mac, StaParams);
2914 }
2915
2916 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2917 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2918
2919 if (!status)
2920 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002922 "%s: timeout waiting for tdls add station indication",
2923 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002924 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002925 }
2926 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2927 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002929 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002930 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002931 }
2932
2933 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002934
2935error:
2936 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2937 return -EPERM;
2938
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002939}
2940#endif
2941
Jeff Johnson295189b2012-06-20 16:38:30 -07002942static int wlan_hdd_change_station(struct wiphy *wiphy,
2943 struct net_device *dev,
2944 u8 *mac,
2945 struct station_parameters *params)
2946{
2947 VOS_STATUS status = VOS_STATUS_SUCCESS;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302949 hdd_context_t *pHddCtx;
2950 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002951 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002952#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002953 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002954 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002955#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002956 ENTER();
2957
Gopichand Nakkala29149562013-05-10 21:43:41 +05302958 if ((NULL == pAdapter))
2959 {
2960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2961 "invalid adapter ");
2962 return -EINVAL;
2963 }
2964
2965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2966 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2967
2968 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2969 {
2970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2971 "invalid HDD state or HDD station context");
2972 return -EINVAL;
2973 }
2974
2975 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002976 {
2977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2978 "%s:LOGP in Progress. Ignore!!!", __func__);
2979 return -EAGAIN;
2980 }
2981
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2983
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002984 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2985 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002986 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002987 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302989 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002990 WLANTL_STA_AUTHENTICATED);
2991
Gopichand Nakkala29149562013-05-10 21:43:41 +05302992 if (status != VOS_STATUS_SUCCESS)
2993 {
2994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2995 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2996 return -EINVAL;
2997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002998 }
2999 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003000 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3001 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303002#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003003 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3004 StaParams.capability = params->capability;
3005 StaParams.uapsd_queues = params->uapsd_queues;
3006 StaParams.max_sp = params->max_sp;
3007
3008 if (0 != params->ext_capab_len)
3009 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3010 sizeof(StaParams.extn_capability));
3011
3012 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003013 {
3014 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003015 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003016 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003017
3018 StaParams.supported_rates_len = params->supported_rates_len;
3019
3020 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3021 * The supported_rates array , for all the structures propogating till Add Sta
3022 * to the firmware has to be modified , if the supplicant (ieee80211) is
3023 * modified to send more rates.
3024 */
3025
3026 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3027 */
3028 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3029 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3030
3031 if (0 != StaParams.supported_rates_len) {
3032 int i = 0;
3033 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3034 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003036 "Supported Rates with Length %d", StaParams.supported_rates_len);
3037 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003039 "[%d]: %0x", i, StaParams.supported_rates[i]);
3040 }
3041
3042 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003043 {
3044 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003045 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003046 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003047
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003048 if (0 != params->ext_capab_len ) {
3049 /*Define A Macro : TODO Sunil*/
3050 if ((1<<4) & StaParams.extn_capability[3]) {
3051 isBufSta = 1;
3052 }
3053 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303054 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3055 params->max_sp, isBufSta);
3056 if (VOS_STATUS_SUCCESS != status) {
3057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3058 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3059 return -EINVAL;
3060 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003061 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3062
3063 if (VOS_STATUS_SUCCESS != status) {
3064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3065 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3066 return -EINVAL;
3067 }
3068 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003069#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303070 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003071 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 return status;
3073}
3074
3075/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 * FUNCTION: wlan_hdd_cfg80211_add_key
3077 * This function is used to initialize the key information
3078 */
3079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003080static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003081 struct net_device *ndev,
3082 u8 key_index, bool pairwise,
3083 const u8 *mac_addr,
3084 struct key_params *params
3085 )
3086#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003087static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 struct net_device *ndev,
3089 u8 key_index, const u8 *mac_addr,
3090 struct key_params *params
3091 )
3092#endif
3093{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 tCsrRoamSetKey setKey;
3096 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303097 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003098 v_U32_t roamId= 0xFF;
3099 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 hdd_hostapd_state_t *pHostapdState;
3101 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003102 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303103 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 ENTER();
3106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3108 status = wlan_hdd_validate_context(pHddCtx);
3109
3110 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: HDD context is not valid", __func__);
3114 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003115 }
3116
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3118 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 if (CSR_MAX_NUM_KEY <= key_index)
3121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 key_index);
3124
3125 return -EINVAL;
3126 }
3127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003128 if (CSR_MAX_KEY_LEN < params->key_len)
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3131 params->key_len);
3132
3133 return -EINVAL;
3134 }
3135
3136 hddLog(VOS_TRACE_LEVEL_INFO,
3137 "%s: called with key index = %d & key length %d",
3138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003139
3140 /*extract key idx, key len and key*/
3141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3142 setKey.keyId = key_index;
3143 setKey.keyLength = params->key_len;
3144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 {
3148 case WLAN_CIPHER_SUITE_WEP40:
3149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3150 break;
3151
3152 case WLAN_CIPHER_SUITE_WEP104:
3153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3154 break;
3155
3156 case WLAN_CIPHER_SUITE_TKIP:
3157 {
3158 u8 *pKey = &setKey.Key[0];
3159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3160
3161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003164
3165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 |--------------|----------|----------|
3168 <---16bytes---><--8bytes--><--8bytes-->
3169
3170 */
3171 /*Sme expects the 32 bytes key to be in the below order
3172
3173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 |--------------|----------|----------|
3176 <---16bytes---><--8bytes--><--8bytes-->
3177 */
3178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180
3181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187
3188 break;
3189 }
3190
3191 case WLAN_CIPHER_SUITE_CCMP:
3192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3193 break;
3194
3195#ifdef FEATURE_WLAN_WAPI
3196 case WLAN_CIPHER_SUITE_SMS4:
3197 {
3198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3200 params->key, params->key_len);
3201 return 0;
3202 }
3203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205#ifdef FEATURE_WLAN_CCX
3206 case WLAN_CIPHER_SUITE_KRK:
3207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3208 break;
3209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003210
3211#ifdef WLAN_FEATURE_11W
3212 case WLAN_CIPHER_SUITE_AES_CMAC:
3213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003215#endif
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 default:
3218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3219 __func__, params->cipher);
3220 return -EOPNOTSUPP;
3221 }
3222
3223 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3224 __func__, setKey.encType);
3225
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003226 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3228 (!pairwise)
3229#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003230 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003231#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003232 )
3233 {
3234 /* set group key*/
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s- %d: setting Broadcast key",
3237 __func__, __LINE__);
3238 setKey.keyDirection = eSIR_RX_ONLY;
3239 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3240 }
3241 else
3242 {
3243 /* set pairwise key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s- %d: setting pairwise key",
3246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_TX_RX;
3248 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3249 }
3250 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3251 {
3252 setKey.keyDirection = eSIR_TX_RX;
3253 /*Set the group key*/
3254 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3255 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003256
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003257 if ( 0 != status )
3258 {
3259 hddLog(VOS_TRACE_LEVEL_ERROR,
3260 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3261 return -EINVAL;
3262 }
3263 /*Save the keys here and call sme_RoamSetKey for setting
3264 the PTK after peer joins the IBSS network*/
3265 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3266 &setKey, sizeof(tCsrRoamSetKey));
3267 return status;
3268 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303269 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3270 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3271 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003272 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003273 if( pHostapdState->bssState == BSS_START )
3274 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3276
3277 if ( status != eHAL_STATUS_SUCCESS )
3278 {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3280 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3281 __LINE__, status );
3282 }
3283 }
3284
3285 /* Saving WEP keys */
3286 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3287 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3288 {
3289 //Save the wep key in ap context. Issue setkey after the BSS is started.
3290 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3291 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3292 }
3293 else
3294 {
3295 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003296 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3298 }
3299 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003300 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3301 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003302 {
3303 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3304 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3305
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3307 if (!pairwise)
3308#else
3309 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3310#endif
3311 {
3312 /* set group key*/
3313 if (pHddStaCtx->roam_info.deferKeyComplete)
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3316 "%s- %d: Perform Set key Complete",
3317 __func__, __LINE__);
3318 hdd_PerformRoamSetKeyComplete(pAdapter);
3319 }
3320 }
3321
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3323
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003324 pWextState->roamProfile.Keys.defaultIndex = key_index;
3325
3326
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003327 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003328 params->key, params->key_len);
3329
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303330
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3332
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303333 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303335 __func__, setKey.peerMac[0], setKey.peerMac[1],
3336 setKey.peerMac[2], setKey.peerMac[3],
3337 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003338 setKey.keyDirection);
3339
3340 vos_status = wlan_hdd_check_ula_done(pAdapter);
3341
3342 if ( vos_status != VOS_STATUS_SUCCESS )
3343 {
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3345 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3346 __LINE__, vos_status );
3347
3348 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3349
3350 return -EINVAL;
3351
3352 }
3353
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003354#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303355 /* The supplicant may attempt to set the PTK once pre-authentication
3356 is done. Save the key in the UMAC and include it in the ADD BSS
3357 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003358 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303359 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003360 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303361 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3362 "%s: Update PreAuth Key success", __func__);
3363 return 0;
3364 }
3365 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR,
3368 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303369 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003370 }
3371#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003372
3373 /* issue set key request to SME*/
3374 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3375 pAdapter->sessionId, &setKey, &roamId );
3376
3377 if ( 0 != status )
3378 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303379 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3381 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3382 return -EINVAL;
3383 }
3384
3385
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303386 /* in case of IBSS as there was no information available about WEP keys during
3387 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3390 !( ( IW_AUTH_KEY_MGMT_802_1X
3391 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003392 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3393 )
3394 &&
3395 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3396 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3397 )
3398 )
3399 {
3400 setKey.keyDirection = eSIR_RX_ONLY;
3401 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303403 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003404 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303405 __func__, setKey.peerMac[0], setKey.peerMac[1],
3406 setKey.peerMac[2], setKey.peerMac[3],
3407 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 setKey.keyDirection);
3409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303410 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 pAdapter->sessionId, &setKey, &roamId );
3412
3413 if ( 0 != status )
3414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 __func__, status);
3418 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3419 return -EINVAL;
3420 }
3421 }
3422 }
3423
3424 return 0;
3425}
3426
3427/*
3428 * FUNCTION: wlan_hdd_cfg80211_get_key
3429 * This function is used to get the key information
3430 */
3431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303432static int wlan_hdd_cfg80211_get_key(
3433 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303435 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003436 const u8 *mac_addr, void *cookie,
3437 void (*callback)(void *cookie, struct key_params*)
3438 )
3439#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303440static int wlan_hdd_cfg80211_get_key(
3441 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003442 struct net_device *ndev,
3443 u8 key_index, const u8 *mac_addr, void *cookie,
3444 void (*callback)(void *cookie, struct key_params*)
3445 )
3446#endif
3447{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3450 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3451 struct key_params params;
3452
3453 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303454
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3456 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 memset(&params, 0, sizeof(params));
3459
3460 if (CSR_MAX_NUM_KEY <= key_index)
3461 {
3462 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003464
3465 switch(pRoamProfile->EncryptionType.encryptionType[0])
3466 {
3467 case eCSR_ENCRYPT_TYPE_NONE:
3468 params.cipher = IW_AUTH_CIPHER_NONE;
3469 break;
3470
3471 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3472 case eCSR_ENCRYPT_TYPE_WEP40:
3473 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3474 break;
3475
3476 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3477 case eCSR_ENCRYPT_TYPE_WEP104:
3478 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3479 break;
3480
3481 case eCSR_ENCRYPT_TYPE_TKIP:
3482 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3483 break;
3484
3485 case eCSR_ENCRYPT_TYPE_AES:
3486 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3487 break;
3488
3489 default:
3490 params.cipher = IW_AUTH_CIPHER_NONE;
3491 break;
3492 }
3493
3494 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3495 params.seq_len = 0;
3496 params.seq = NULL;
3497 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3498 callback(cookie, &params);
3499 return 0;
3500}
3501
3502/*
3503 * FUNCTION: wlan_hdd_cfg80211_del_key
3504 * This function is used to delete the key information
3505 */
3506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303507static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303509 u8 key_index,
3510 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 const u8 *mac_addr
3512 )
3513#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303514static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 struct net_device *ndev,
3516 u8 key_index,
3517 const u8 *mac_addr
3518 )
3519#endif
3520{
3521 int status = 0;
3522
3523 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 //it is observed that this is invalidating peer
3526 //key index whenever re-key is done. This is affecting data link.
3527 //It should be ok to ignore del_key.
3528#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3530 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003531 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3532 tCsrRoamSetKey setKey;
3533 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303534
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 ENTER();
3536
3537 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3538 __func__,pAdapter->device_mode);
3539
3540 if (CSR_MAX_NUM_KEY <= key_index)
3541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 key_index);
3544
3545 return -EINVAL;
3546 }
3547
3548 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3549 setKey.keyId = key_index;
3550
3551 if (mac_addr)
3552 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3553 else
3554 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3555
3556 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3557
3558 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003559 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560 )
3561 {
3562
3563 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003564 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3565 if( pHostapdState->bssState == BSS_START)
3566 {
3567 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303568
Jeff Johnson295189b2012-06-20 16:38:30 -07003569 if ( status != eHAL_STATUS_SUCCESS )
3570 {
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3573 __LINE__, status );
3574 }
3575 }
3576 }
3577 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303578 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 )
3580 {
3581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303583 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3584
3585 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303587 __func__, setKey.peerMac[0], setKey.peerMac[1],
3588 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303590 if(pAdapter->sessionCtx.station.conn_info.connState ==
3591 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303593 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 if ( 0 != status )
3597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 "%s: sme_RoamSetKey failure, returned %d",
3600 __func__, status);
3601 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3602 return -EINVAL;
3603 }
3604 }
3605 }
3606#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003607 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 return status;
3609}
3610
3611/*
3612 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3613 * This function is used to set the default tx key index
3614 */
3615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3616static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3617 struct net_device *ndev,
3618 u8 key_index,
3619 bool unicast, bool multicast)
3620#else
3621static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3622 struct net_device *ndev,
3623 u8 key_index)
3624#endif
3625{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303627 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303628 hdd_wext_state_t *pWextState;
3629 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303630 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003631
3632 ENTER();
3633
Gopichand Nakkala29149562013-05-10 21:43:41 +05303634 if ((NULL == pAdapter))
3635 {
3636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3637 "invalid adapter");
3638 return -EINVAL;
3639 }
3640
3641 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3642 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3643
3644 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3645 {
3646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3647 "invalid Wext state or HDD context");
3648 return -EINVAL;
3649 }
3650
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3652 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303653
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 if (CSR_MAX_NUM_KEY <= key_index)
3655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 key_index);
3658
3659 return -EINVAL;
3660 }
3661
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3663 status = wlan_hdd_validate_context(pHddCtx);
3664
3665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3668 "%s: HDD context is not valid", __func__);
3669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303671
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003673 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303674 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303676 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003679 pWextState->roamProfile.EncryptionType.encryptionType[0])
3680 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303681 {
3682 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303684
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 tCsrRoamSetKey setKey;
3686 v_U32_t roamId= 0xFF;
3687 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688
3689 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 Keys->defaultIndex = (u8)key_index;
3693 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3694 setKey.keyId = key_index;
3695 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696
3697 vos_mem_copy(&setKey.Key[0],
3698 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303700
Gopichand Nakkala29149562013-05-10 21:43:41 +05303701 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303702
3703 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 &pHddStaCtx->conn_info.bssId[0],
3705 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706
Gopichand Nakkala29149562013-05-10 21:43:41 +05303707 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3708 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3709 eCSR_ENCRYPT_TYPE_WEP104)
3710 {
3711 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3712 even though ap is configured for WEP-40 encryption. In this canse the key length
3713 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3714 type(104) and switching encryption type to 40*/
3715 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3716 eCSR_ENCRYPT_TYPE_WEP40;
3717 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3718 eCSR_ENCRYPT_TYPE_WEP40;
3719 }
3720
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303725 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303727
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 if ( 0 != status )
3729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003732 status);
3733 return -EINVAL;
3734 }
3735 }
3736 }
3737
3738 /* In SoftAp mode setting key direction for default mode */
3739 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3740 {
3741 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3742 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3743 (eCSR_ENCRYPT_TYPE_AES !=
3744 pWextState->roamProfile.EncryptionType.encryptionType[0])
3745 )
3746 {
3747 /* Saving key direction for default key index to TX default */
3748 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3749 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3750 }
3751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303752
Jeff Johnson295189b2012-06-20 16:38:30 -07003753 return status;
3754}
3755
Jeff Johnson295189b2012-06-20 16:38:30 -07003756/*
3757 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3758 * This function is used to inform the BSS details to nl80211 interface.
3759 */
3760static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3761 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3762{
3763 struct net_device *dev = pAdapter->dev;
3764 struct wireless_dev *wdev = dev->ieee80211_ptr;
3765 struct wiphy *wiphy = wdev->wiphy;
3766 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3767 int chan_no;
3768 int ie_length;
3769 const char *ie;
3770 unsigned int freq;
3771 struct ieee80211_channel *chan;
3772 int rssi = 0;
3773 struct cfg80211_bss *bss = NULL;
3774
3775 ENTER();
3776
3777 if( NULL == pBssDesc )
3778 {
3779 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3780 return bss;
3781 }
3782
3783 chan_no = pBssDesc->channelId;
3784 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3785 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3786
3787 if( NULL == ie )
3788 {
3789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3790 return bss;
3791 }
3792
3793#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3794 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3795 {
3796 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3797 }
3798 else
3799 {
3800 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3801 }
3802#else
3803 freq = ieee80211_channel_to_frequency(chan_no);
3804#endif
3805
3806 chan = __ieee80211_get_channel(wiphy, freq);
3807
3808 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3809 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3810 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3811 if (bss == NULL)
3812 {
3813 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3814
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303815 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3816 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003817 pBssDesc->capabilityInfo,
3818 pBssDesc->beaconInterval, ie, ie_length,
3819 rssi, GFP_KERNEL ));
3820}
3821 else
3822 {
3823 return bss;
3824 }
3825}
3826
3827
3828
3829/*
3830 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3831 * This function is used to inform the BSS details to nl80211 interface.
3832 */
3833struct cfg80211_bss*
3834wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3835 tSirBssDescription *bss_desc
3836 )
3837{
3838 /*
3839 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3840 already exists in bss data base of cfg80211 for that particular BSS ID.
3841 Using cfg80211_inform_bss_frame to update the bss entry instead of
3842 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3843 now there is no possibility to get the mgmt(probe response) frame from PE,
3844 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3845 cfg80211_inform_bss_frame.
3846 */
3847 struct net_device *dev = pAdapter->dev;
3848 struct wireless_dev *wdev = dev->ieee80211_ptr;
3849 struct wiphy *wiphy = wdev->wiphy;
3850 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003851#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3852 qcom_ie_age *qie_age = NULL;
3853 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3854#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 const char *ie =
3858 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3859 unsigned int freq;
3860 struct ieee80211_channel *chan;
3861 struct ieee80211_mgmt *mgmt =
3862 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3863 struct cfg80211_bss *bss_status = NULL;
3864 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3865 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003866#ifdef WLAN_OPEN_SOURCE
3867 struct timespec ts;
3868#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003869
3870 ENTER();
3871
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003872 if (!mgmt)
3873 return NULL;
3874
Jeff Johnson295189b2012-06-20 16:38:30 -07003875 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003876
3877#ifdef WLAN_OPEN_SOURCE
3878 /* Android does not want the timestamp from the frame.
3879 Instead it wants a monotonic increasing value */
3880 get_monotonic_boottime(&ts);
3881 mgmt->u.probe_resp.timestamp =
3882 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3883#else
3884 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3886 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003887
3888#endif
3889
Jeff Johnson295189b2012-06-20 16:38:30 -07003890 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3891 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003892
3893#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3894 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3895 /* Assuming this is the last IE, copy at the end */
3896 ie_length -=sizeof(qcom_ie_age);
3897 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3898 qie_age->element_id = QCOM_VENDOR_IE_ID;
3899 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3900 qie_age->oui_1 = QCOM_OUI1;
3901 qie_age->oui_2 = QCOM_OUI2;
3902 qie_age->oui_3 = QCOM_OUI3;
3903 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3904 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3905#endif
3906
Jeff Johnson295189b2012-06-20 16:38:30 -07003907 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303908 if (bss_desc->fProbeRsp)
3909 {
3910 mgmt->frame_control |=
3911 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3912 }
3913 else
3914 {
3915 mgmt->frame_control |=
3916 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003918
3919#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3922 {
3923 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303925 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003926 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3927
3928 {
3929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3930 }
3931 else
3932 {
3933 kfree(mgmt);
3934 return NULL;
3935 }
3936#else
3937 freq = ieee80211_channel_to_frequency(chan_no);
3938#endif
3939 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003940 /*when the band is changed on the fly using the GUI, three things are done
3941 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
3942 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3943 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3944 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3945 * and discards the channels correponding to previous band and calls back with zero bss results.
3946 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
3947 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3948 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3949 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3950 * So drop the bss and continue to next bss.
3951 */
3952 if(chan == NULL)
3953 {
3954 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003955 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003956 return NULL;
3957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303959 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 * */
3961 if (( eConnectionState_Associated ==
3962 pAdapter->sessionCtx.station.conn_info.connState ) &&
3963 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3964 pAdapter->sessionCtx.station.conn_info.bssId,
3965 WNI_CFG_BSSID_LEN)))
3966 {
3967 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3968 rssi = (pAdapter->rssi * 100);
3969 }
3970 else
3971 {
3972 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3973 }
3974
3975 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3976 frame_len, rssi, GFP_KERNEL);
3977 kfree(mgmt);
3978 return bss_status;
3979}
3980
3981/*
3982 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3983 * This function is used to update the BSS data base of CFG8011
3984 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303985struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 tCsrRoamInfo *pRoamInfo
3987 )
3988{
3989 tCsrRoamConnectedProfile roamProfile;
3990 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3991 struct cfg80211_bss *bss = NULL;
3992
3993 ENTER();
3994
3995 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3996 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3997
3998 if (NULL != roamProfile.pBssDesc)
3999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304000 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 &roamProfile);
4002
4003 if (NULL == bss)
4004 {
4005 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4006 __func__);
4007 }
4008
4009 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4010 }
4011 else
4012 {
4013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4014 __func__);
4015 }
4016 return bss;
4017}
4018
4019/*
4020 * FUNCTION: wlan_hdd_cfg80211_update_bss
4021 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304022static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4023 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304025{
Jeff Johnson295189b2012-06-20 16:38:30 -07004026 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4027 tCsrScanResultInfo *pScanResult;
4028 eHalStatus status = 0;
4029 tScanResultHandle pResult;
4030 struct cfg80211_bss *bss_status = NULL;
4031
4032 ENTER();
4033
4034 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4035 {
4036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4037 return -EAGAIN;
4038 }
4039
4040 /*
4041 * start getting scan results and populate cgf80211 BSS database
4042 */
4043 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4044
4045 /* no scan results */
4046 if (NULL == pResult)
4047 {
4048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4049 return status;
4050 }
4051
4052 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4053
4054 while (pScanResult)
4055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 /*
4057 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4058 * entry already exists in bss data base of cfg80211 for that
4059 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4060 * bss entry instead of cfg80211_inform_bss, But this call expects
4061 * mgmt packet as input. As of now there is no possibility to get
4062 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 * ieee80211_mgmt(probe response) and passing to c
4064 * fg80211_inform_bss_frame.
4065 * */
4066
4067 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4068 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304069
Jeff Johnson295189b2012-06-20 16:38:30 -07004070
4071 if (NULL == bss_status)
4072 {
4073 hddLog(VOS_TRACE_LEVEL_INFO,
4074 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4075 }
4076 else
4077 {
4078 cfg80211_put_bss(bss_status);
4079 }
4080
4081 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4082 }
4083
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304084 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004085
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304086 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004087}
4088
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004089void
4090hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4091{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004093 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4094 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4095 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004096} /****** end hddPrintMacAddr() ******/
4097
4098void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004099hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304101 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004102 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4103 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4104 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4105 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004106} /****** end hddPrintPmkId() ******/
4107
4108//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4109//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4110
4111//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4112//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4113
4114#define dump_bssid(bssid) \
4115 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004116 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4117 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4118 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004119 }
4120
4121#define dump_pmkid(pMac, pmkid) \
4122 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004123 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4124 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4125 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004126 }
4127
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004128#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004129/*
4130 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4131 * This function is used to notify the supplicant of a new PMKSA candidate.
4132 */
4133int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004135 int index, bool preauth )
4136{
Jeff Johnsone7245742012-09-05 17:12:55 -07004137#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004139 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004140
4141 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004142 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143
4144 if( NULL == pRoamInfo )
4145 {
4146 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4147 return -EINVAL;
4148 }
4149
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4151 {
4152 dump_bssid(pRoamInfo->bssid);
4153 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004154 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004155 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004156#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004158}
4159#endif //FEATURE_WLAN_LFR
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161/*
4162 * FUNCTION: hdd_cfg80211_scan_done_callback
4163 * scanning callback function, called after finishing scan
4164 *
4165 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4168{
4169 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304170 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004172 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4173 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 struct cfg80211_scan_request *req = NULL;
4175 int ret = 0;
4176
4177 ENTER();
4178
4179 hddLog(VOS_TRACE_LEVEL_INFO,
4180 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 __func__, halHandle, pContext, (int) scanId, (int) status);
4183
4184 //Block on scan req completion variable. Can't wait forever though.
4185 ret = wait_for_completion_interruptible_timeout(
4186 &pScanInfo->scan_req_completion_event,
4187 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4188 if (!ret)
4189 {
4190 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004191 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 }
4193
4194 if(pScanInfo->mScanPending != VOS_TRUE)
4195 {
4196 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004197 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 }
4199
4200 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304201 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 {
4203 hddLog(VOS_TRACE_LEVEL_INFO,
4204 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304205 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 (int) scanId);
4207 }
4208
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304209 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 pAdapter);
4211
4212 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004214
4215
4216 /* If any client wait scan result through WEXT
4217 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004218 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 /* The other scan request waiting for current scan finish
4221 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004222 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004224 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 }
4226 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004227 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 {
4229 struct net_device *dev = pAdapter->dev;
4230 union iwreq_data wrqu;
4231 int we_event;
4232 char *msg;
4233
4234 memset(&wrqu, '\0', sizeof(wrqu));
4235 we_event = SIOCGIWSCAN;
4236 msg = NULL;
4237 wireless_send_event(dev, we_event, &wrqu, msg);
4238 }
4239 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004240 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004241
4242 /* Get the Scan Req */
4243 req = pAdapter->request;
4244
4245 if (!req)
4246 {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004248 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004249 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 }
4251
4252 /*
4253 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304254 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004255 req->n_ssids = 0;
4256 req->n_channels = 0;
4257 req->ie = 0;
4258
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004260 /* Scan is no longer pending */
4261 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004262
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004263 /*
4264 * cfg80211_scan_done informing NL80211 about completion
4265 * of scanning
4266 */
4267 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004268 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Jeff Johnsone7245742012-09-05 17:12:55 -07004270allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004271 /* release the wake lock at the end of the scan*/
4272 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004273
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004274 /* Acquire wakelock to handle the case where APP's tries to suspend
4275 * immediatly after the driver gets connect request(i.e after scan)
4276 * from supplicant, this result in app's is suspending and not able
4277 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004278 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004279
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004280#ifdef FEATURE_WLAN_TDLS
4281 wlan_hdd_tdls_scan_done_callback(pAdapter);
4282#endif
4283
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 EXIT();
4285 return 0;
4286}
4287
4288/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004289 * FUNCTION: hdd_isScanAllowed
4290 * Go through each adapter and check if scan allowed
4291 *
4292 */
4293v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4294{
4295 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4296 hdd_station_ctx_t *pHddStaCtx = NULL;
4297 hdd_adapter_t *pAdapter = NULL;
4298 VOS_STATUS status = 0;
4299 v_U8_t staId = 0;
4300 v_U8_t *staMac = NULL;
4301
4302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4303
4304 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4305 {
4306 pAdapter = pAdapterNode->pAdapter;
4307
4308 if( pAdapter )
4309 {
4310 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304311 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004312 __func__, pAdapter->device_mode);
4313 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4314 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4315 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4316 {
4317 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4318 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4319 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4320 {
4321 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304324 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004325 staMac[0], staMac[1], staMac[2],
4326 staMac[3], staMac[4], staMac[5]);
4327 return VOS_FALSE;
4328 }
4329 }
4330 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4331 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4332 {
4333 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004336 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4337 {
4338 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4339
4340 hddLog(VOS_TRACE_LEVEL_ERROR,
4341 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004343 staMac[0], staMac[1], staMac[2],
4344 staMac[3], staMac[4], staMac[5]);
4345 return VOS_FALSE;
4346 }
4347 }
4348 }
4349 }
4350 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4351 pAdapterNode = pNext;
4352 }
4353 hddLog(VOS_TRACE_LEVEL_INFO,
4354 "%s: Scan allowed", __func__);
4355 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304356}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004357
4358/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004359 * FUNCTION: wlan_hdd_cfg80211_scan
4360 * this scan respond to scan trigger and update cfg80211 scan database
4361 * later, scan dump command can be used to recieve scan results
4362 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004363int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4364#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4365 struct net_device *dev,
4366#endif
4367 struct cfg80211_scan_request *request)
4368{
4369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4370 struct net_device *dev = request->wdev->netdev;
4371#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4374 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304375 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 tCsrScanRequest scanRequest;
4377 tANI_U8 *channelList = NULL, i;
4378 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304379 int status;
4380 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004382
4383 ENTER();
4384
4385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4386 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304388 status = wlan_hdd_validate_context(pHddCtx);
4389
4390 if (0 != status)
4391 {
4392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4393 "%s: HDD context is not valid", __func__);
4394 return status;
4395 }
4396
4397 cfg_param = pHddCtx->cfg_ini;
4398 pScanInfo = &pHddCtx->scan_info;
4399
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004400 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004401 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004402 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004403 {
4404 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004405 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4406 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004407 return -EBUSY;
4408 }
4409
Jeff Johnson295189b2012-06-20 16:38:30 -07004410#ifdef WLAN_BTAMP_FEATURE
4411 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004412 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004413 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 "%s: No scanning when AMP is on", __func__);
4416 return -EOPNOTSUPP;
4417 }
4418#endif
4419 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 "%s: Not scanning on device_mode = %d",
4424 __func__, pAdapter->device_mode);
4425 return -EOPNOTSUPP;
4426 }
4427
4428 if (TRUE == pScanInfo->mScanPending)
4429 {
4430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004431 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004432 }
4433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304434 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004435 //Channel and action frame is pending
4436 //Otherwise Cancel Remain On Channel and allow Scan
4437 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004438 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004439 {
4440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4441 return -EBUSY;
4442 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004443#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004444 /* if tdls disagree scan right now, return immediately.
4445 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4446 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4447 */
4448 status = wlan_hdd_tdls_scan_callback (pAdapter,
4449 wiphy,
4450#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4451 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004452#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004453 request);
4454 if(status <= 0)
4455 {
4456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4457 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004458 }
4459#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004460
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4462 {
4463 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004464 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4468 {
4469 hddLog(VOS_TRACE_LEVEL_WARN,
4470 "%s: MAX TM Level Scan not allowed", __func__);
4471 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304472 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004473 }
4474 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4475
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004476 /* Check if scan is allowed at this point of time.
4477 */
4478 if (!hdd_isScanAllowed(pHddCtx))
4479 {
4480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4481 return -EBUSY;
4482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304483
Jeff Johnson295189b2012-06-20 16:38:30 -07004484 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4485
4486 if (NULL != request)
4487 {
4488 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304489 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004490
4491 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4492 * Becasue of this, driver is assuming that this is not wildcard scan and so
4493 * is not aging out the scan results.
4494 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004495 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 {
4497 request->n_ssids = 0;
4498 }
4499
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004500 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 {
4502 tCsrSSIDInfo *SsidInfo;
4503 int j;
4504 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4505 /* Allocate num_ssid tCsrSSIDInfo structure */
4506 SsidInfo = scanRequest.SSIDs.SSIDList =
4507 ( tCsrSSIDInfo *)vos_mem_malloc(
4508 request->n_ssids*sizeof(tCsrSSIDInfo));
4509
4510 if(NULL == scanRequest.SSIDs.SSIDList)
4511 {
4512 hddLog(VOS_TRACE_LEVEL_ERROR,
4513 "memory alloc failed SSIDInfo buffer");
4514 return -ENOMEM;
4515 }
4516
4517 /* copy all the ssid's and their length */
4518 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4519 {
4520 /* get the ssid length */
4521 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4522 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4523 SsidInfo->SSID.length);
4524 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4525 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4526 j, SsidInfo->SSID.ssId);
4527 }
4528 /* set the scan type to active */
4529 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4530 }
4531 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4532 {
4533 /* set the scan type to active */
4534 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4535 }
4536 else
4537 {
4538 /*Set the scan type to default type, in this case it is ACTIVE*/
4539 scanRequest.scanType = pScanInfo->scan_mode;
4540 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4543 }
4544 else
4545 {
4546 /* set the scan type to active */
4547 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4548 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4549
4550 /* set min and max channel time to zero */
4551 scanRequest.minChnTime = 0;
4552 scanRequest.maxChnTime = 0;
4553 }
4554
4555 /* set BSSType to default type */
4556 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4557
4558 /*TODO: scan the requested channels only*/
4559
4560 /*Right now scanning all the channels */
4561 if( request )
4562 {
4563 if( request->n_channels )
4564 {
4565 channelList = vos_mem_malloc( request->n_channels );
4566 if( NULL == channelList )
4567 {
4568 status = -ENOMEM;
4569 goto free_mem;
4570 }
4571
4572 for( i = 0 ; i < request->n_channels ; i++ )
4573 channelList[i] = request->channels[i]->hw_value;
4574 }
4575
4576 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4577 scanRequest.ChannelInfo.ChannelList = channelList;
4578
4579 /* set requestType to full scan */
4580 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581
4582 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004583 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004585 */
4586
4587 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588 * and in that case driver shoudnt flush scan results. If
4589 * driver flushes the scan results here and unfortunately if
4590 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004591 * fails which is not desired
4592 */
4593
4594 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4595 {
4596 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4597 pAdapter->sessionId );
4598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004599
4600 if( request->ie_len )
4601 {
4602 /* save this for future association (join requires this) */
4603 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4604 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4605 pScanInfo->scanAddIE.length = request->ie_len;
4606
4607 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004608 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4609 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004610 )
4611 {
4612 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4613 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4614 }
4615
4616 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4617 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4618
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4620 request->ie_len);
4621 if (pP2pIe != NULL)
4622 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004623#ifdef WLAN_FEATURE_P2P_DEBUG
4624 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4625 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4626 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4627 {
4628 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4629 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4630 "Go nego completed to Connection is started");
4631 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4632 "for 8way Handshake");
4633 }
4634 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4635 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4636 {
4637 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4639 "Disconnected state to Connection is started");
4640 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4641 "for 4way Handshake");
4642 }
4643#endif
4644
Jeff Johnsone7245742012-09-05 17:12:55 -07004645 /* no_cck will be set during p2p find to disable 11b rates */
4646 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 hddLog(VOS_TRACE_LEVEL_INFO,
4649 "%s: This is a P2P Search", __func__);
4650 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004651
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4653 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004654 /* set requestType to P2P Discovery */
4655 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004656 }
4657
4658 /*
4659 Skip Dfs Channel in case of P2P Search
4660 if it is set in ini file
4661 */
4662 if(cfg_param->skipDfsChnlInP2pSearch)
4663 {
4664 scanRequest.skipDfsChnlInP2pSearch = 1;
4665 }
4666 else
4667 {
4668 scanRequest.skipDfsChnlInP2pSearch = 0;
4669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004670
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 }
4672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 }
4674 }
4675
4676 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4677
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004678 /* acquire the wakelock to avoid the apps suspend during the scan. To
4679 * address the following issues.
4680 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4681 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4682 * for long time, this result in apps running at full power for long time.
4683 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4684 * be stuck in full power because of resume BMPS
4685 */
4686 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004687
4688 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 pAdapter->sessionId, &scanRequest, &scanId,
4690 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004691
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 if (eHAL_STATUS_SUCCESS != status)
4693 {
4694 hddLog(VOS_TRACE_LEVEL_ERROR,
4695 "%s: sme_ScanRequest returned error %d", __func__, status);
4696 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004697 if(eHAL_STATUS_RESOURCES == status)
4698 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: HO is in progress.So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004700 status = -EBUSY;
4701 } else {
4702 status = -EIO;
4703 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004704 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 goto free_mem;
4706 }
4707
4708 pScanInfo->mScanPending = TRUE;
4709 pAdapter->request = request;
4710 pScanInfo->scanId = scanId;
4711
4712 complete(&pScanInfo->scan_req_completion_event);
4713
4714free_mem:
4715 if( scanRequest.SSIDs.SSIDList )
4716 {
4717 vos_mem_free(scanRequest.SSIDs.SSIDList);
4718 }
4719
4720 if( channelList )
4721 vos_mem_free( channelList );
4722
4723 EXIT();
4724
4725 return status;
4726}
4727
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004728
4729void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4730{
4731 v_U8_t iniDot11Mode =
4732 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4733 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4734
4735 switch ( iniDot11Mode )
4736 {
4737 case eHDD_DOT11_MODE_AUTO:
4738 case eHDD_DOT11_MODE_11ac:
4739 case eHDD_DOT11_MODE_11ac_ONLY:
4740#ifdef WLAN_FEATURE_11AC
4741 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4742#else
4743 hddDot11Mode = eHDD_DOT11_MODE_11n;
4744#endif
4745 break;
4746 case eHDD_DOT11_MODE_11n:
4747 case eHDD_DOT11_MODE_11n_ONLY:
4748 hddDot11Mode = eHDD_DOT11_MODE_11n;
4749 break;
4750 default:
4751 hddDot11Mode = iniDot11Mode;
4752 break;
4753 }
4754 /* This call decides required channel bonding mode */
4755 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4756 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4757 operationChannel);
4758}
4759
Jeff Johnson295189b2012-06-20 16:38:30 -07004760/*
4761 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304762 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304764int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004765 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004766{
4767 int status = 0;
4768 hdd_wext_state_t *pWextState;
4769 v_U32_t roamId;
4770 tCsrRoamProfile *pRoamProfile;
4771 eMib_dot11DesiredBssType connectedBssType;
4772 eCsrAuthType RSNAuthType;
4773
4774 ENTER();
4775
4776 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304777
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4779 {
4780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4781 return -EINVAL;
4782 }
4783
4784 pRoamProfile = &pWextState->roamProfile;
4785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304786 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004788 int ret = 0;
4789 hdd_station_ctx_t *pHddStaCtx;
4790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4791 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4792
4793 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4794 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4795 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 {
4797 /* Issue disconnect to CSR */
4798 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304799 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4801 pAdapter->sessionId,
4802 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4803 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004804 ret = wait_for_completion_interruptible_timeout(
4805 &pAdapter->disconnect_comp_var,
4806 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4807 if (0 == ret)
4808 {
4809 VOS_ASSERT(0);
4810 }
4811 }
4812 }
4813 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4814 {
4815 ret = wait_for_completion_interruptible_timeout(
4816 &pAdapter->disconnect_comp_var,
4817 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4818 if (0 == ret)
4819 {
4820 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 }
4822 }
4823
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304824 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4826 {
4827 /*QoS not enabled in cfg file*/
4828 pRoamProfile->uapsd_mask = 0;
4829 }
4830 else
4831 {
4832 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304833 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4835 }
4836
4837 pRoamProfile->SSIDs.numOfSSIDs = 1;
4838 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4839 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4842 ssid, ssid_len);
4843
4844 if (bssid)
4845 {
4846 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4847 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4848 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304849 /* Save BSSID in seperate variable as well, as RoamProfile
4850 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 case of join failure we should send valid BSSID to supplicant
4852 */
4853 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4854 WNI_CFG_BSSID_LEN);
4855 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07004856 else
4857 {
4858 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
4859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004860
4861 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4862 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304863 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 /*set gen ie*/
4865 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4866 /*set auth*/
4867 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4868 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004869#ifdef FEATURE_WLAN_WAPI
4870 if (pAdapter->wapi_info.nWapiMode)
4871 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004872 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 switch (pAdapter->wapi_info.wapiAuthMode)
4874 {
4875 case WAPI_AUTH_MODE_PSK:
4876 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004877 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004878 pAdapter->wapi_info.wapiAuthMode);
4879 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4880 break;
4881 }
4882 case WAPI_AUTH_MODE_CERT:
4883 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004884 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 pAdapter->wapi_info.wapiAuthMode);
4886 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4887 break;
4888 }
4889 } // End of switch
4890 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4891 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4892 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004893 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004894 pRoamProfile->AuthType.numEntries = 1;
4895 pRoamProfile->EncryptionType.numEntries = 1;
4896 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4897 pRoamProfile->mcEncryptionType.numEntries = 1;
4898 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4899 }
4900 }
4901#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304902#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05304903 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304904 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4905 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4906 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05304907 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
4908 sizeof (tSirGtkOffloadParams));
4909 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304910 }
4911#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 pRoamProfile->csrPersona = pAdapter->device_mode;
4913
Jeff Johnson32d95a32012-09-10 13:15:23 -07004914 if( operatingChannel )
4915 {
4916 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4917 pRoamProfile->ChannelInfo.numOfChannels = 1;
4918 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004919 else
4920 {
4921 pRoamProfile->ChannelInfo.ChannelList = NULL;
4922 pRoamProfile->ChannelInfo.numOfChannels = 0;
4923 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004924 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4925 {
4926 hdd_select_cbmode(pAdapter,operatingChannel);
4927 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004928 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4929 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304930 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004931 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004932 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4933 */
4934 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4935 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4936 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304937
4938 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 pAdapter->sessionId, pRoamProfile, &roamId);
4940
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004941 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304942 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4943
4944 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4946 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4947 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304948 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004949 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304950 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004951
4952 pRoamProfile->ChannelInfo.ChannelList = NULL;
4953 pRoamProfile->ChannelInfo.numOfChannels = 0;
4954
Jeff Johnson295189b2012-06-20 16:38:30 -07004955 }
4956 else
4957 {
4958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4959 return -EINVAL;
4960 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004961 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 return status;
4963}
4964
4965/*
4966 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4967 * This function is used to set the authentication type (OPEN/SHARED).
4968 *
4969 */
4970static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4971 enum nl80211_auth_type auth_type)
4972{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304973 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4975
4976 ENTER();
4977
4978 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304979 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004980 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304982 hddLog(VOS_TRACE_LEVEL_INFO,
4983 "%s: set authentication type to AUTOSWITCH", __func__);
4984 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4985 break;
4986
4987 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004988#ifdef WLAN_FEATURE_VOWIFI_11R
4989 case NL80211_AUTHTYPE_FT:
4990#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304991 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 "%s: set authentication type to OPEN", __func__);
4993 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4994 break;
4995
4996 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304997 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 "%s: set authentication type to SHARED", __func__);
4999 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5000 break;
5001#ifdef FEATURE_WLAN_CCX
5002 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305003 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 "%s: set authentication type to CCKM WPA", __func__);
5005 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5006 break;
5007#endif
5008
5009
5010 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305011 hddLog(VOS_TRACE_LEVEL_ERROR,
5012 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 auth_type);
5014 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5015 return -EINVAL;
5016 }
5017
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305018 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 pHddStaCtx->conn_info.authType;
5020 return 0;
5021}
5022
5023/*
5024 * FUNCTION: wlan_hdd_set_akm_suite
5025 * This function is used to set the key mgmt type(PSK/8021x).
5026 *
5027 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305028static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005029 u32 key_mgmt
5030 )
5031{
5032 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5033 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305034
Jeff Johnson295189b2012-06-20 16:38:30 -07005035 /*set key mgmt type*/
5036 switch(key_mgmt)
5037 {
5038 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305039#ifdef WLAN_FEATURE_VOWIFI_11R
5040 case WLAN_AKM_SUITE_FT_PSK:
5041#endif
5042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 __func__);
5044 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5045 break;
5046
5047 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305048#ifdef WLAN_FEATURE_VOWIFI_11R
5049 case WLAN_AKM_SUITE_FT_8021X:
5050#endif
5051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 __func__);
5053 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5054 break;
5055#ifdef FEATURE_WLAN_CCX
5056#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5057#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5058 case WLAN_AKM_SUITE_CCKM:
5059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5060 __func__);
5061 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5062 break;
5063#endif
5064
5065 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005067 __func__, key_mgmt);
5068 return -EINVAL;
5069
5070 }
5071 return 0;
5072}
5073
5074/*
5075 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305076 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 * (NONE/WEP40/WEP104/TKIP/CCMP).
5078 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5080 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 bool ucast
5082 )
5083{
5084 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305085 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5087
5088 ENTER();
5089
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305090 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 __func__, cipher);
5094 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5095 }
5096 else
5097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305098
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305100 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 {
5102 case IW_AUTH_CIPHER_NONE:
5103 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5104 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305107 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305111 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 case WLAN_CIPHER_SUITE_TKIP:
5115 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5116 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305117
Jeff Johnson295189b2012-06-20 16:38:30 -07005118 case WLAN_CIPHER_SUITE_CCMP:
5119 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5120 break;
5121#ifdef FEATURE_WLAN_WAPI
5122 case WLAN_CIPHER_SUITE_SMS4:
5123 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5124 break;
5125#endif
5126
5127#ifdef FEATURE_WLAN_CCX
5128 case WLAN_CIPHER_SUITE_KRK:
5129 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5130 break;
5131#endif
5132 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 __func__, cipher);
5135 return -EOPNOTSUPP;
5136 }
5137 }
5138
5139 if (ucast)
5140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 __func__, encryptionType);
5143 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5144 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305145 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 encryptionType;
5147 }
5148 else
5149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005151 __func__, encryptionType);
5152 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5153 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5154 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5155 }
5156
5157 return 0;
5158}
5159
5160
5161/*
5162 * FUNCTION: wlan_hdd_cfg80211_set_ie
5163 * This function is used to parse WPA/RSN IE's.
5164 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305165int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5166 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005167 size_t ie_len
5168 )
5169{
5170 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5171 u8 *genie = ie;
5172 v_U16_t remLen = ie_len;
5173#ifdef FEATURE_WLAN_WAPI
5174 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5175 u16 *tmp;
5176 v_U16_t akmsuiteCount;
5177 int *akmlist;
5178#endif
5179 ENTER();
5180
5181 /* clear previous assocAddIE */
5182 pWextState->assocAddIE.length = 0;
5183 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5184
5185 while (remLen >= 2)
5186 {
5187 v_U16_t eLen = 0;
5188 v_U8_t elementId;
5189 elementId = *genie++;
5190 eLen = *genie++;
5191 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305192
5193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305195
5196 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305198 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005199 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 -07005200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 "%s: Invalid WPA IE", __func__);
5203 return -EINVAL;
5204 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305205 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 {
5207 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305208 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305210
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5212 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005213 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5214 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005215 VOS_ASSERT(0);
5216 return -ENOMEM;
5217 }
5218 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5219 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5220 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305221
Jeff Johnson295189b2012-06-20 16:38:30 -07005222 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5223 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5224 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305226 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5227 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005228 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5229 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5230 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5231 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5232 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5233 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5235 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 /*Consider P2P IE, only for P2P Client */
5237 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5238 {
5239 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305240 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005241 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5244 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005245 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5246 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 VOS_ASSERT(0);
5248 return -ENOMEM;
5249 }
5250 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5251 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5252 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305253
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5255 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005257#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305258 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5259 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 /*Consider WFD IE, only for P2P Client */
5261 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5262 {
5263 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305264 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305266
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5268 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005269 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5270 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 VOS_ASSERT(0);
5272 return -ENOMEM;
5273 }
5274 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5275 // WPS IE + P2P IE + WFD IE
5276 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5277 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305278
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5280 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5281 }
5282#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005283 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305284 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005285 HS20_OUI_TYPE_SIZE)) )
5286 {
5287 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305288 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005289 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005290
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005291 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5292 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005293 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5294 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005295 VOS_ASSERT(0);
5296 return -ENOMEM;
5297 }
5298 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5299 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005301 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5302 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5303 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005304
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 break;
5306 case DOT11F_EID_RSN:
5307 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5308 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5309 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5310 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5311 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5312 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005313 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5314 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305315 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005316 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305317 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005318 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305319
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005320 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5321 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005322 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5323 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005324 VOS_ASSERT(0);
5325 return -ENOMEM;
5326 }
5327 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5328 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305329
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005330 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5331 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5332 break;
5333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005334#ifdef FEATURE_WLAN_WAPI
5335 case WLAN_EID_WAPI:
5336 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5337 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5338 pAdapter->wapi_info.nWapiMode);
5339 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305340 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 akmsuiteCount = WPA_GET_LE16(tmp);
5342 tmp = tmp + 1;
5343 akmlist = (int *)(tmp);
5344 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5345 {
5346 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5347 }
5348 else
5349 {
5350 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5351 VOS_ASSERT(0);
5352 return -EINVAL;
5353 }
5354
5355 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5356 {
5357 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005358 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305362 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005363 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005364 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5366 }
5367 break;
5368#endif
5369 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305370 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005371 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005372 /* when Unknown IE is received we should break and continue
5373 * to the next IE in the buffer instead we were returning
5374 * so changing this to break */
5375 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 }
5377 genie += eLen;
5378 remLen -= eLen;
5379 }
5380 EXIT();
5381 return 0;
5382}
5383
5384/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305385 * FUNCTION: hdd_isWPAIEPresent
5386 * Parse the received IE to find the WPA IE
5387 *
5388 */
5389static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5390{
5391 v_U8_t eLen = 0;
5392 v_U16_t remLen = ie_len;
5393 v_U8_t elementId = 0;
5394
5395 while (remLen >= 2)
5396 {
5397 elementId = *ie++;
5398 eLen = *ie++;
5399 remLen -= 2;
5400 if (eLen > remLen)
5401 {
5402 hddLog(VOS_TRACE_LEVEL_ERROR,
5403 "%s: IE length is wrong %d", __func__, eLen);
5404 return FALSE;
5405 }
5406 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5407 {
5408 /* OUI - 0x00 0X50 0XF2
5409 WPA Information Element - 0x01
5410 WPA version - 0x01*/
5411 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5412 return TRUE;
5413 }
5414 ie += eLen;
5415 remLen -= eLen;
5416 }
5417 return FALSE;
5418}
5419
5420/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305422 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 * parameters during connect operation.
5424 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305425int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 struct cfg80211_connect_params *req
5427 )
5428{
5429 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 ENTER();
5432
5433 /*set wpa version*/
5434 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5435
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305436 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 {
5438 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305439 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305440 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305442 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 * since p2p ie is also put in same buffer.
5444 * */
5445 {
5446 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5447 }
5448 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5449 {
5450 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5451 }
5452 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453
5454 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 pWextState->wpaVersion);
5456
5457 /*set authentication type*/
5458 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5459
5460 if (0 > status)
5461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305462 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005463 "%s: failed to set authentication type ", __func__);
5464 return status;
5465 }
5466
5467 /*set key mgmt type*/
5468 if (req->crypto.n_akm_suites)
5469 {
5470 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5471 if (0 > status)
5472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 __func__);
5475 return status;
5476 }
5477 }
5478
5479 /*set pairwise cipher type*/
5480 if (req->crypto.n_ciphers_pairwise)
5481 {
5482 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5483 req->crypto.ciphers_pairwise[0], true);
5484 if (0 > status)
5485 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305486 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 "%s: failed to set unicast cipher type", __func__);
5488 return status;
5489 }
5490 }
5491 else
5492 {
5493 /*Reset previous cipher suite to none*/
5494 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5495 if (0 > status)
5496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305497 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 "%s: failed to set unicast cipher type", __func__);
5499 return status;
5500 }
5501 }
5502
5503 /*set group cipher type*/
5504 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5505 false);
5506
5507 if (0 > status)
5508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 __func__);
5511 return status;
5512 }
5513
Chet Lanctot186b5732013-03-18 10:26:30 -07005514#ifdef WLAN_FEATURE_11W
5515 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5516#endif
5517
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5519 if (req->ie_len)
5520 {
5521 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5522 if ( 0 > status)
5523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 __func__);
5526 return status;
5527 }
5528 }
5529
5530 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 {
5533 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5534 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5535 )
5536 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305537 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 __func__);
5542 return -EOPNOTSUPP;
5543 }
5544 else
5545 {
5546 u8 key_len = req->key_len;
5547 u8 key_idx = req->key_idx;
5548
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305549 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 && (CSR_MAX_NUM_KEY > key_idx)
5551 )
5552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553 hddLog(VOS_TRACE_LEVEL_INFO,
5554 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 __func__, key_idx, key_len);
5556 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305559 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 (u8)key_len;
5561 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5562 }
5563 }
5564 }
5565 }
5566
5567 return status;
5568}
5569
5570/*
5571 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305572 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005573 * parameters during connect operation.
5574 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305575static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 struct net_device *ndev,
5577 struct cfg80211_connect_params *req
5578 )
5579{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305580 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5583 hdd_context_t *pHddCtx = NULL;
5584
5585 ENTER();
5586
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5589
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305590 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5591 status = wlan_hdd_validate_context(pHddCtx);
5592
5593 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5596 "%s: HDD context is not valid", __func__);
5597 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 }
5599
5600#ifdef WLAN_BTAMP_FEATURE
5601 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305602 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305604 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005606 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 }
5608#endif
5609 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005611
5612 if ( 0 > status)
5613 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 __func__);
5616 return status;
5617 }
5618
5619 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005620 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5622 (vos_concurrent_sessions_running()))
5623 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305624 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 }
5626
Mohit Khanna765234a2012-09-11 15:08:35 -07005627 if ( req->channel )
5628 {
5629 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5630 req->ssid_len, req->bssid,
5631 req->channel->hw_value);
5632 }
5633 else
5634 {
5635 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305636 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005638
5639 if (0 > status)
5640 {
5641 //ReEnable BMPS if disabled
5642 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5643 (NULL != pHddCtx))
5644 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305645 if (pHddCtx->hdd_wlan_suspended)
5646 {
5647 hdd_set_pwrparams(pHddCtx);
5648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 //ReEnable Bmps and Imps back
5650 hdd_enable_bmps_imps(pHddCtx);
5651 }
5652
5653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5654 return status;
5655 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305656 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 EXIT();
5658 return status;
5659}
5660
5661
5662/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305663 * FUNCTION: wlan_hdd_disconnect
5664 * This function is used to issue a disconnect request to SME
5665 */
5666int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5667{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305668 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305670 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5671
5672 status = wlan_hdd_validate_context(pHddCtx);
5673
5674 if (0 != status)
5675 {
5676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5677 "%s: HDD context is not valid", __func__);
5678 return status;
5679 }
5680
5681 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305682 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305683 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305684
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305685 /*issue disconnect*/
5686 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5687 pAdapter->sessionId, reason);
5688
5689 if ( 0 != status )
5690 {
5691 hddLog(VOS_TRACE_LEVEL_ERROR,
5692 "%s csrRoamDisconnect failure, returned %d \n",
5693 __func__, (int)status );
5694 return -EINVAL;
5695 }
5696 wait_for_completion_interruptible_timeout(
5697 &pAdapter->disconnect_comp_var,
5698 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5699 /*stop tx queues*/
5700 netif_tx_disable(pAdapter->dev);
5701 netif_carrier_off(pAdapter->dev);
5702 return status;
5703}
5704
5705
5706/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 * FUNCTION: wlan_hdd_cfg80211_disconnect
5708 * This function is used to issue a disconnect request to SME
5709 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305710static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 struct net_device *dev,
5712 u16 reason
5713 )
5714{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305715 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5716 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005717 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305718 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005720 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305721#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005722 tANI_U8 staIdx;
5723#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305724
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305726
5727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 __func__,pAdapter->device_mode);
5729
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5731 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005732
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305733 status = wlan_hdd_validate_context(pHddCtx);
5734
5735 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5738 "%s: HDD context is not valid", __func__);
5739 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305741
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 if (NULL != pRoamProfile)
5743 {
5744 /*issue disconnect request to SME, if station is in connected state*/
5745 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5746 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305747 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305749 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 switch(reason)
5751 {
5752 case WLAN_REASON_MIC_FAILURE:
5753 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5754 break;
5755
5756 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5757 case WLAN_REASON_DISASSOC_AP_BUSY:
5758 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5759 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5760 break;
5761
5762 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5763 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5764 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5765 break;
5766
5767 case WLAN_REASON_DEAUTH_LEAVING:
5768 default:
5769 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5770 break;
5771 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305772 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5773 pScanInfo = &pHddCtx->scan_info;
5774 if (pScanInfo->mScanPending)
5775 {
5776 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5777 "Aborting Scan");
5778 hdd_abort_mac_scan(pHddCtx);
5779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005780
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005781#ifdef FEATURE_WLAN_TDLS
5782 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005783 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005784 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005785 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5786 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005787 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005788 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005789 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005790 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005791 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005792 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005793 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005794 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005795 pAdapter->sessionId,
5796 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005797 }
5798 }
5799#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305800 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5801 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 {
5803 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305804 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 __func__, (int)status );
5806 return -EINVAL;
5807 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 }
5809 }
5810 else
5811 {
5812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5813 }
5814
5815 return status;
5816}
5817
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305818
Jeff Johnson295189b2012-06-20 16:38:30 -07005819/*
5820 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 * settings in IBSS mode.
5823 */
5824static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 struct cfg80211_ibss_params *params
5827 )
5828{
5829 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305830 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 ENTER();
5835
5836 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5837
5838 if (params->ie_len && ( NULL != params->ie) )
5839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305840 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 {
5842 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5843 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5844 }
5845 else
5846 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005847 tDot11fIEWPA dot11WPAIE;
5848 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5849
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005851 // Unpack the WPA IE
5852 //Skip past the EID byte and length byte - and four byte WiFi OUI
5853 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5854 &params->ie[2+4],
5855 params->ie[1] - 4,
5856 &dot11WPAIE);
5857 /*Extract the multicast cipher, the encType for unicast
5858 cipher for wpa-none is none*/
5859 encryptionType =
5860 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 }
5862 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5863
5864 if (0 > status)
5865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 __func__);
5868 return status;
5869 }
5870 }
5871
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 pWextState->roamProfile.AuthType.authType[0] =
5873 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5875
5876 if (params->privacy)
5877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305878 /* Security enabled IBSS, At this time there is no information available
5879 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305883 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 *enable privacy bit in beacons */
5885
5886 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5887 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005888 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5889 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5891 pWextState->roamProfile.EncryptionType.numEntries = 1;
5892 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 return status;
5894}
5895
5896/*
5897 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305898 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 struct net_device *dev,
5902 struct cfg80211_ibss_params *params
5903 )
5904{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005906 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5907 tCsrRoamProfile *pRoamProfile;
5908 int status;
5909 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305910 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005911
5912 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305913
5914 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5916
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305917 status = wlan_hdd_validate_context(pHddCtx);
5918
5919 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5922 "%s: HDD context is not valid", __func__);
5923 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 }
5925
5926 if (NULL == pWextState)
5927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305928 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 __func__);
5930 return -EIO;
5931 }
5932
5933 pRoamProfile = &pWextState->roamProfile;
5934
5935 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305937 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 "%s Interface type is not set to IBSS \n", __func__);
5939 return -EINVAL;
5940 }
5941
5942 /* Set Channel */
5943 if (NULL != params->channel)
5944 {
5945 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005946 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5947 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5948 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5949 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005950
5951 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 ieee80211_frequency_to_channel(params->channel->center_freq);
5954
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005955
5956 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5957 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5960 __func__);
5961 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005963
5964 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005966 if (channelNum == validChan[indx])
5967 {
5968 break;
5969 }
5970 }
5971 if (indx >= numChans)
5972 {
5973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 __func__, channelNum);
5975 return -EINVAL;
5976 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005977 /* Set the Operational Channel */
5978 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5979 channelNum);
5980 pRoamProfile->ChannelInfo.numOfChannels = 1;
5981 pHddStaCtx->conn_info.operationChannel = channelNum;
5982 pRoamProfile->ChannelInfo.ChannelList =
5983 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 }
5985
5986 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305987 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 if (status < 0)
5989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 __func__);
5992 return status;
5993 }
5994
5995 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305996 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005997 params->ssid_len, params->bssid,
5998 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005999
6000 if (0 > status)
6001 {
6002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6003 return status;
6004 }
6005
6006 return 0;
6007}
6008
6009/*
6010 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 struct net_device *dev
6015 )
6016{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6019 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306020 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6021 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006022
6023 ENTER();
6024
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306025 status = wlan_hdd_validate_context(pHddCtx);
6026
6027 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6030 "%s: HDD context is not valid", __func__);
6031 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006032 }
6033
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6035 if (NULL == pWextState)
6036 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 __func__);
6039 return -EIO;
6040 }
6041
6042 pRoamProfile = &pWextState->roamProfile;
6043
6044 /* Issue disconnect only if interface type is set to IBSS */
6045 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306047 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 __func__);
6049 return -EINVAL;
6050 }
6051
6052 /* Issue Disconnect request */
6053 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6054 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6055 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6056
6057 return 0;
6058}
6059
6060/*
6061 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6062 * This function is used to set the phy parameters
6063 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6064 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306065static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 u32 changed)
6067{
6068 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6069 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306070 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006071
6072 ENTER();
6073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306074 status = wlan_hdd_validate_context(pHddCtx);
6075
6076 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6079 "%s: HDD context is not valid", __func__);
6080 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006081 }
6082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6084 {
6085 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6086 WNI_CFG_RTS_THRESHOLD_STAMAX :
6087 wiphy->rts_threshold;
6088
6089 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306090 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306092 hddLog(VOS_TRACE_LEVEL_ERROR,
6093 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 __func__, rts_threshold);
6095 return -EINVAL;
6096 }
6097
6098 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6099 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306102 hddLog(VOS_TRACE_LEVEL_ERROR,
6103 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 __func__, rts_threshold);
6105 return -EIO;
6106 }
6107
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 rts_threshold);
6110 }
6111
6112 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6113 {
6114 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6115 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6116 wiphy->frag_threshold;
6117
6118 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306119 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306121 hddLog(VOS_TRACE_LEVEL_ERROR,
6122 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006123 frag_threshold);
6124 return -EINVAL;
6125 }
6126
6127 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6128 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306129 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306131 hddLog(VOS_TRACE_LEVEL_ERROR,
6132 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 __func__, frag_threshold);
6134 return -EIO;
6135 }
6136
6137 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6138 frag_threshold);
6139 }
6140
6141 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6142 || (changed & WIPHY_PARAM_RETRY_LONG))
6143 {
6144 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6145 wiphy->retry_short :
6146 wiphy->retry_long;
6147
6148 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6149 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6150 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 __func__, retry_value);
6153 return -EINVAL;
6154 }
6155
6156 if (changed & WIPHY_PARAM_RETRY_SHORT)
6157 {
6158 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6159 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306160 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306162 hddLog(VOS_TRACE_LEVEL_ERROR,
6163 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 __func__, retry_value);
6165 return -EIO;
6166 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306167 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 __func__, retry_value);
6169 }
6170 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6171 {
6172 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6173 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306174 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306176 hddLog(VOS_TRACE_LEVEL_ERROR,
6177 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 __func__, retry_value);
6179 return -EIO;
6180 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 __func__, retry_value);
6183 }
6184 }
6185
6186 return 0;
6187}
6188
6189/*
6190 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6191 * This function is used to set the txpower
6192 */
6193static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6194#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306195 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006196#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306197 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006198#endif
6199 int dbm)
6200{
6201 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306202 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6204 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306205 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006206
6207 ENTER();
6208
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306209 status = wlan_hdd_validate_context(pHddCtx);
6210
6211 if (0 != status)
6212 {
6213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6214 "%s: HDD context is not valid", __func__);
6215 return status;
6216 }
6217
6218 hHal = pHddCtx->hHal;
6219
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306220 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6221 dbm, ccmCfgSetCallback,
6222 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6226 return -EIO;
6227 }
6228
6229 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6230 dbm);
6231
6232 switch(type)
6233 {
6234 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6235 /* Fall through */
6236 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6237 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6238 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6240 __func__);
6241 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 }
6243 break;
6244 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 __func__);
6247 return -EOPNOTSUPP;
6248 break;
6249 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6251 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 return -EIO;
6253 }
6254
6255 return 0;
6256}
6257
6258/*
6259 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6260 * This function is used to read the txpower
6261 */
6262static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6263{
6264
6265 hdd_adapter_t *pAdapter;
6266 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306267 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006268
Jeff Johnsone7245742012-09-05 17:12:55 -07006269 ENTER();
6270
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306271 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306273 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006274 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6276 "%s: HDD context is not valid", __func__);
6277 *dbm = 0;
6278 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006279 }
6280
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6282 if (NULL == pAdapter)
6283 {
6284 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6285 return -ENOENT;
6286 }
6287
6288 wlan_hdd_get_classAstats(pAdapter);
6289 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6290
Jeff Johnsone7245742012-09-05 17:12:55 -07006291 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 return 0;
6293}
6294
6295static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6296 u8* mac, struct station_info *sinfo)
6297{
6298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6299 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6300 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6301 tANI_U8 rate_flags;
6302
6303 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6304 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006305
6306 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6307 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6308 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6309 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6310 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6311 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6312 tANI_U16 maxRate = 0;
6313 tANI_U16 myRate;
6314 tANI_U16 currentRate = 0;
6315 tANI_U8 maxSpeedMCS = 0;
6316 tANI_U8 maxMCSIdx = 0;
6317 tANI_U8 rateFlag = 1;
6318 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006319 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306320 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006321
Leo Chang6f8870f2013-03-26 18:11:36 -07006322#ifdef WLAN_FEATURE_11AC
6323 tANI_U32 vht_mcs_map;
6324 eDataRate11ACMaxMcs vhtMaxMcs;
6325#endif /* WLAN_FEATURE_11AC */
6326
Jeff Johnsone7245742012-09-05 17:12:55 -07006327 ENTER();
6328
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6330 (0 == ssidlen))
6331 {
6332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6333 " Invalid ssidlen, %d", __func__, ssidlen);
6334 /*To keep GUI happy*/
6335 return 0;
6336 }
6337
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306338 status = wlan_hdd_validate_context(pHddCtx);
6339
6340 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006341 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6343 "%s: HDD context is not valid", __func__);
6344 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006345 }
6346
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6348 sinfo->filled |= STATION_INFO_SIGNAL;
6349
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006350 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6352
6353 //convert to the UI units of 100kbps
6354 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6355
6356#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006357 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 -07006358 sinfo->signal,
6359 pCfg->reportMaxLinkSpeed,
6360 myRate,
6361 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006362 (int) pCfg->linkSpeedRssiMid,
6363 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006364 (int) rate_flags,
6365 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006366#endif //LINKSPEED_DEBUG_ENABLED
6367
6368 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6369 {
6370 // we do not want to necessarily report the current speed
6371 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6372 {
6373 // report the max possible speed
6374 rssidx = 0;
6375 }
6376 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6377 {
6378 // report the max possible speed with RSSI scaling
6379 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6380 {
6381 // report the max possible speed
6382 rssidx = 0;
6383 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006384 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 {
6386 // report middle speed
6387 rssidx = 1;
6388 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006389 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6390 {
6391 // report middle speed
6392 rssidx = 2;
6393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 else
6395 {
6396 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006397 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 }
6399 }
6400 else
6401 {
6402 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6403 hddLog(VOS_TRACE_LEVEL_ERROR,
6404 "%s: Invalid value for reportMaxLinkSpeed: %u",
6405 __func__, pCfg->reportMaxLinkSpeed);
6406 rssidx = 0;
6407 }
6408
6409 maxRate = 0;
6410
6411 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306412 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6413 OperationalRates, &ORLeng))
6414 {
6415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6416 /*To keep GUI happy*/
6417 return 0;
6418 }
6419
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 for (i = 0; i < ORLeng; i++)
6421 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
6424 /* Validate Rate Set */
6425 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6426 {
6427 currentRate = supported_data_rate[j].supported_rate[rssidx];
6428 break;
6429 }
6430 }
6431 /* Update MAX rate */
6432 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6433 }
6434
6435 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306436 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6437 ExtendedRates, &ERLeng))
6438 {
6439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6440 /*To keep GUI happy*/
6441 return 0;
6442 }
6443
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 for (i = 0; i < ERLeng; i++)
6445 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006446 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 {
6448 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6449 {
6450 currentRate = supported_data_rate[j].supported_rate[rssidx];
6451 break;
6452 }
6453 }
6454 /* Update MAX rate */
6455 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 /* Get MCS Rate Set -- but only if we are connected at MCS
6458 rates or if we are always reporting max speed or if we have
6459 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006460 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306462 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6463 MCSRates, &MCSLeng))
6464 {
6465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6466 /*To keep GUI happy*/
6467 return 0;
6468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006470#ifdef WLAN_FEATURE_11AC
6471 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306472 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006474 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306475 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006476 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006478 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006480 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006482 maxMCSIdx = 7;
6483 }
6484 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6485 {
6486 maxMCSIdx = 8;
6487 }
6488 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6489 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306490 //VHT20 is supporting 0~8
6491 if (rate_flags & eHAL_TX_RATE_VHT20)
6492 maxMCSIdx = 8;
6493 else
6494 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006495 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306496
6497 if (rate_flags & eHAL_TX_RATE_VHT80)
6498 {
6499 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6500 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6501 }
6502 else if (rate_flags & eHAL_TX_RATE_VHT40)
6503 {
6504 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6505 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6506 }
6507 else if (rate_flags & eHAL_TX_RATE_VHT20)
6508 {
6509 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6510 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6511 }
6512
Leo Chang6f8870f2013-03-26 18:11:36 -07006513 maxSpeedMCS = 1;
6514 if (currentRate > maxRate)
6515 {
6516 maxRate = currentRate;
6517 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306518
Leo Chang6f8870f2013-03-26 18:11:36 -07006519 }
6520 else
6521#endif /* WLAN_FEATURE_11AC */
6522 {
6523 if (rate_flags & eHAL_TX_RATE_HT40)
6524 {
6525 rateFlag |= 1;
6526 }
6527 if (rate_flags & eHAL_TX_RATE_SGI)
6528 {
6529 rateFlag |= 2;
6530 }
6531
6532 for (i = 0; i < MCSLeng; i++)
6533 {
6534 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6535 for (j = 0; j < temp; j++)
6536 {
6537 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6538 {
6539 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6540 break;
6541 }
6542 }
6543 if ((j < temp) && (currentRate > maxRate))
6544 {
6545 maxRate = currentRate;
6546 maxSpeedMCS = 1;
6547 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 }
6550 }
6551 }
6552
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306553 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6554 {
6555 maxRate = myRate;
6556 maxSpeedMCS = 1;
6557 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6558 }
6559
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006561 if (((maxRate < myRate) && (0 == rssidx)) ||
6562 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 {
6564 maxRate = myRate;
6565 if (rate_flags & eHAL_TX_RATE_LEGACY)
6566 {
6567 maxSpeedMCS = 0;
6568 }
6569 else
6570 {
6571 maxSpeedMCS = 1;
6572 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6573 }
6574 }
6575
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306576 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 {
6578 sinfo->txrate.legacy = maxRate;
6579#ifdef LINKSPEED_DEBUG_ENABLED
6580 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6581#endif //LINKSPEED_DEBUG_ENABLED
6582 }
6583 else
6584 {
6585 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006586#ifdef WLAN_FEATURE_11AC
6587 sinfo->txrate.nss = 1;
6588 if (rate_flags & eHAL_TX_RATE_VHT80)
6589 {
6590 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306591 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006592 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306593 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006594 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306595 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6596 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6597 }
6598 else if (rate_flags & eHAL_TX_RATE_VHT20)
6599 {
6600 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6601 }
6602#endif /* WLAN_FEATURE_11AC */
6603 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6604 {
6605 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6606 if (rate_flags & eHAL_TX_RATE_HT40)
6607 {
6608 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6609 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 if (rate_flags & eHAL_TX_RATE_SGI)
6612 {
6613 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6614 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306615
Jeff Johnson295189b2012-06-20 16:38:30 -07006616#ifdef LINKSPEED_DEBUG_ENABLED
6617 pr_info("Reporting MCS rate %d flags %x\n",
6618 sinfo->txrate.mcs,
6619 sinfo->txrate.flags );
6620#endif //LINKSPEED_DEBUG_ENABLED
6621 }
6622 }
6623 else
6624 {
6625 // report current rate instead of max rate
6626
6627 if (rate_flags & eHAL_TX_RATE_LEGACY)
6628 {
6629 //provide to the UI in units of 100kbps
6630 sinfo->txrate.legacy = myRate;
6631#ifdef LINKSPEED_DEBUG_ENABLED
6632 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6633#endif //LINKSPEED_DEBUG_ENABLED
6634 }
6635 else
6636 {
6637 //must be MCS
6638 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006639#ifdef WLAN_FEATURE_11AC
6640 sinfo->txrate.nss = 1;
6641 if (rate_flags & eHAL_TX_RATE_VHT80)
6642 {
6643 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6644 }
6645 else
6646#endif /* WLAN_FEATURE_11AC */
6647 {
6648 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 if (rate_flags & eHAL_TX_RATE_SGI)
6651 {
6652 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6653 }
6654 if (rate_flags & eHAL_TX_RATE_HT40)
6655 {
6656 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6657 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006658#ifdef WLAN_FEATURE_11AC
6659 else if (rate_flags & eHAL_TX_RATE_VHT80)
6660 {
6661 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6662 }
6663#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006664#ifdef LINKSPEED_DEBUG_ENABLED
6665 pr_info("Reporting actual MCS rate %d flags %x\n",
6666 sinfo->txrate.mcs,
6667 sinfo->txrate.flags );
6668#endif //LINKSPEED_DEBUG_ENABLED
6669 }
6670 }
6671 sinfo->filled |= STATION_INFO_TX_BITRATE;
6672
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006673 sinfo->tx_packets =
6674 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6675 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6676 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6677 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6678
6679 sinfo->tx_retries =
6680 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6681 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6682 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6683 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6684
6685 sinfo->tx_failed =
6686 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6687 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6688 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6689 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6690
6691 sinfo->filled |=
6692 STATION_INFO_TX_PACKETS |
6693 STATION_INFO_TX_RETRIES |
6694 STATION_INFO_TX_FAILED;
6695
6696 EXIT();
6697 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006698}
6699
6700static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07006701 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07006702{
6703 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306704 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306706 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006707
Jeff Johnsone7245742012-09-05 17:12:55 -07006708 ENTER();
6709
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 if (NULL == pAdapter)
6711 {
6712 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6713 return -ENODEV;
6714 }
6715
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306716 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306717 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306718
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306719 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306720 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6722 "%s: HDD context is not valid", __func__);
6723 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306724 }
6725
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306726 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6727 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6728 (pHddCtx->cfg_ini->fhostArpOffload) &&
6729 (eConnectionState_Associated ==
6730 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6731 {
6732 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6733 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6734 {
6735 hddLog(VOS_TRACE_LEVEL_INFO,
6736 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6737 __func__, vos_status);
6738 }
6739 }
6740
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 /**The get power cmd from the supplicant gets updated by the nl only
6742 *on successful execution of the function call
6743 *we are oppositely mapped w.r.t mode in the driver
6744 **/
6745 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6746
Jeff Johnsone7245742012-09-05 17:12:55 -07006747 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 if (VOS_STATUS_E_FAILURE == vos_status)
6749 {
6750 return -EINVAL;
6751 }
6752 return 0;
6753}
6754
6755
6756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6757static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6758 struct net_device *netdev,
6759 u8 key_index)
6760{
Jeff Johnsone7245742012-09-05 17:12:55 -07006761 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 return 0;
6763}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006765
6766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6767static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6768 struct net_device *dev,
6769 struct ieee80211_txq_params *params)
6770{
Jeff Johnsone7245742012-09-05 17:12:55 -07006771 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 return 0;
6773}
6774#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6775static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6776 struct ieee80211_txq_params *params)
6777{
Jeff Johnsone7245742012-09-05 17:12:55 -07006778 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 return 0;
6780}
6781#endif //LINUX_VERSION_CODE
6782
6783static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6784 struct net_device *dev, u8 *mac)
6785{
6786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306787 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006788 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306789 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006790 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006791
Jeff Johnsone7245742012-09-05 17:12:55 -07006792 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306793 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 return -EINVAL;
6797 }
6798
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306799 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6800 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006801
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306802 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006803 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6805 "%s: HDD context is not valid", __func__);
6806 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006807 }
6808
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 )
6812 {
6813 if( NULL == mac )
6814 {
6815 v_U16_t i;
6816 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6817 {
6818 if(pAdapter->aStaInfo[i].isUsed)
6819 {
6820 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6821 hddLog(VOS_TRACE_LEVEL_INFO,
6822 "%s: Delete STA with MAC::"
6823 "%02x:%02x:%02x:%02x:%02x:%02x",
6824 __func__,
6825 macAddr[0], macAddr[1], macAddr[2],
6826 macAddr[3], macAddr[4], macAddr[5]);
6827 hdd_softap_sta_deauth(pAdapter, macAddr);
6828 }
6829 }
6830 }
6831 else
6832 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006833
6834 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6835 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6836 {
6837 hddLog(VOS_TRACE_LEVEL_INFO,
6838 "%s: Skip this DEL STA as this is not used::"
6839 "%02x:%02x:%02x:%02x:%02x:%02x",
6840 __func__,
6841 mac[0], mac[1], mac[2],
6842 mac[3], mac[4], mac[5]);
6843 return -ENOENT;
6844 }
6845
6846 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6847 {
6848 hddLog(VOS_TRACE_LEVEL_INFO,
6849 "%s: Skip this DEL STA as deauth is in progress::"
6850 "%02x:%02x:%02x:%02x:%02x:%02x",
6851 __func__,
6852 mac[0], mac[1], mac[2],
6853 mac[3], mac[4], mac[5]);
6854 return -ENOENT;
6855 }
6856
6857 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6858
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 hddLog(VOS_TRACE_LEVEL_INFO,
6860 "%s: Delete STA with MAC::"
6861 "%02x:%02x:%02x:%02x:%02x:%02x",
6862 __func__,
6863 mac[0], mac[1], mac[2],
6864 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006865
6866 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6867 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6868 {
6869 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6870 hddLog(VOS_TRACE_LEVEL_INFO,
6871 "%s: STA removal failed for ::"
6872 "%02x:%02x:%02x:%02x:%02x:%02x",
6873 __func__,
6874 mac[0], mac[1], mac[2],
6875 mac[3], mac[4], mac[5]);
6876 return -ENOENT;
6877 }
6878
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 }
6880 }
6881
6882 EXIT();
6883
6884 return 0;
6885}
6886
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006887static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6888 struct net_device *dev, u8 *mac, struct station_parameters *params)
6889{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006890 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006891#ifdef FEATURE_WLAN_TDLS
6892 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006893 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006894 mask = params->sta_flags_mask;
6895
6896 set = params->sta_flags_set;
6897
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006898#ifdef WLAN_FEATURE_TDLS_DEBUG
6899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6900 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6901 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6902#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006903
6904 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6905 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006906 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006907 }
6908 }
6909#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006910 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006911}
6912
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006913
6914#ifdef FEATURE_WLAN_LFR
6915static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006916 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006917{
6918#define MAX_PMKSAIDS_IN_CACHE 8
6919 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 static tANI_U32 i; // HDD Local Cache index
6921 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006922 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6923 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306925 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006926 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306927 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928
Jeff Johnsone7245742012-09-05 17:12:55 -07006929 ENTER();
6930
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306932 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006933 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006935 return -EINVAL;
6936 }
6937
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6939 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006940
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306941 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006942 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6944 "%s: HDD context is not valid", __func__);
6945 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946 }
6947
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306948 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6950
6951 for (j = 0; j < i; j++)
6952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306953 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006954 pmksa->bssid, WNI_CFG_BSSID_LEN))
6955 {
6956 /* BSSID matched previous entry. Overwrite it. */
6957 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306958 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006959 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306960 vos_mem_copy(PMKIDCache[j].PMKID,
6961 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306963 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006964 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006965 dump_bssid(pmksa->bssid);
6966 dump_pmkid(halHandle, pmksa->pmkid);
6967 break;
6968 }
6969 }
6970
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006971 /* Check we compared all entries,if then take the first slot now */
6972 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6973
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006974 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306975 {
6976 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6977 vos_mem_copy(PMKIDCache[i].BSSID,
6978 pmksa->bssid, ETHER_ADDR_LEN);
6979 vos_mem_copy(PMKIDCache[i].PMKID,
6980 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006981 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006983 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006984 dump_bssid(pmksa->bssid);
6985 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006987 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306988 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006989 }
6990
6991
6992 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306993 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006994 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306995 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006996 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006997 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306998 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6999 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007000 i );
7001 return 0;
7002}
7003
7004
7005static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007006 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007007{
Jeff Johnsone7245742012-09-05 17:12:55 -07007008 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007009 // TODO: Implement this later.
7010 return 0;
7011}
7012
7013static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7014{
Jeff Johnsone7245742012-09-05 17:12:55 -07007015 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007016 // TODO: Implement this later.
7017 return 0;
7018}
7019#endif
7020
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007021#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307022static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007023 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7024{
7025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7026 hdd_station_ctx_t *pHddStaCtx;
7027
7028 if (NULL == pAdapter)
7029 {
7030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7031 return -ENODEV;
7032 }
7033
7034 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7035
7036 // Added for debug on reception of Re-assoc Req.
7037 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7038 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307039 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007040 ftie->ie_len);
7041 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7042 }
7043
7044#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307045 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007046 ftie->ie_len);
7047#endif
7048
7049 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307050 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7051 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007052 ftie->ie_len);
7053 return 0;
7054}
7055#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007056
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307057#ifdef FEATURE_WLAN_SCAN_PNO
7058
7059void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7060 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7061{
7062 int ret;
7063 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7064 hdd_context_t *pHddCtx;
7065
7066 if (NULL == pAdapter)
7067 {
7068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7069 "%s: HDD adapter is Null", __func__);
7070 return ;
7071 }
7072
7073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7074 if (NULL == pHddCtx)
7075 {
7076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7077 "%s: HDD context is Null!!!", __func__);
7078 return ;
7079 }
7080
7081 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7082
7083 if (0 > ret)
7084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7085
7086 cfg80211_sched_scan_results(pHddCtx->wiphy);
7087}
7088
7089/*
7090 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7091 * NL interface to enable PNO
7092 */
7093static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7094 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7095{
7096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7097 tpSirPNOScanReq pPnoRequest = NULL;
7098 hdd_context_t *pHddCtx;
7099 tHalHandle hHal;
7100 v_U32_t i, indx, num_ch;
7101 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7102 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7103 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7104 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307105 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307106
7107 if (NULL == pAdapter)
7108 {
7109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7110 "%s: HDD adapter is Null", __func__);
7111 return -ENODEV;
7112 }
7113
7114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307115 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307116
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307117 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307118 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7120 "%s: HDD context is not valid", __func__);
7121 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307122 }
7123
7124 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7125 if (NULL == hHal)
7126 {
7127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7128 "%s: HAL context is Null!!!", __func__);
7129 return -EAGAIN;
7130 }
7131
7132 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7133 if (NULL == pPnoRequest)
7134 {
7135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7136 "%s: vos_mem_malloc failed", __func__);
7137 return -ENODEV;
7138 }
7139
7140 pPnoRequest->enable = 1; /*Enable PNO */
7141 pPnoRequest->ucNetworksCount = request->n_match_sets;
7142
7143 if (( !pPnoRequest->ucNetworksCount ) ||
7144 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7145 {
7146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7147 "Network input is not correct");
7148 goto error;
7149 }
7150
7151 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7152 {
7153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7154 "Incorrect number of channels");
7155 goto error;
7156 }
7157
7158 /* Framework provides one set of channels(all)
7159 * common for all saved profile */
7160 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7161 channels_allowed, &num_channels_allowed))
7162 {
7163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7164 "%s: failed to get valid channel list", __func__);
7165 goto error;
7166 }
7167 /* Checking each channel against allowed channel list */
7168 num_ch = 0;
7169 for (i = 0; i < request->n_channels; i++)
7170 {
7171 for (indx = 0; indx < num_channels_allowed; indx++)
7172 {
7173 if (request->channels[i]->hw_value == channels_allowed[indx])
7174 {
7175 valid_ch[num_ch++] = request->channels[i]->hw_value;
7176 break ;
7177 }
7178 }
7179 }
7180
7181 /* Filling per profile params */
7182 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7183 {
7184 pPnoRequest->aNetworks[i].ssId.length =
7185 request->match_sets[i].ssid.ssid_len;
7186
7187 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7188 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7189 {
7190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7191 "SSID Len %d is not correct for network %d",
7192 pPnoRequest->aNetworks[i].ssId.length, i);
7193 goto error;
7194 }
7195
7196 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7197 request->match_sets[i].ssid.ssid,
7198 request->match_sets[i].ssid.ssid_len);
7199 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7200 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7201 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7202
7203 /*Copying list of valid channel into request */
7204 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7205 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7206
7207 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7208 }
7209
7210 /* framework provides interval in ms */
7211 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7212 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7213 (request->interval)/1000;
7214 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7215 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7216
7217 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7218 pPnoRequest, pAdapter->sessionId,
7219 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7220 if (eHAL_STATUS_SUCCESS != status)
7221 {
7222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7223 "Failed to enable PNO");
7224 goto error;
7225 }
7226
7227error:
7228 vos_mem_free(pPnoRequest);
7229 return status;
7230}
7231
7232/*
7233 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7234 * NL interface to disable PNO
7235 */
7236static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7237 struct net_device *dev)
7238{
7239 eHalStatus status = eHAL_STATUS_FAILURE;
7240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7241 hdd_context_t *pHddCtx;
7242 tHalHandle hHal;
7243 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307244 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307245
7246 ENTER();
7247
7248 if (NULL == pAdapter)
7249 {
7250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7251 "%s: HDD adapter is Null", __func__);
7252 return -ENODEV;
7253 }
7254
7255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307256 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307257
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307258 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307259 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7261 "%s: HDD context is not valid", __func__);
7262 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307263 }
7264
7265 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7266 if (NULL == hHal)
7267 {
7268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7269 "%s: HAL context is Null!!!", __func__);
7270 return -EAGAIN;
7271 }
7272
7273 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7274 if (NULL == pPnoRequest)
7275 {
7276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7277 "%s: vos_mem_malloc failed", __func__);
7278 return -ENODEV;
7279 }
7280
7281 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7282 pPnoRequest->enable = 0; /* Disable PNO */
7283 pPnoRequest->ucNetworksCount = 0;
7284
7285 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7286 pAdapter->sessionId,
7287 NULL, pAdapter);
7288 if (eHAL_STATUS_SUCCESS != status)
7289 {
7290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7291 "Failed to disabled PNO");
7292 }
7293
7294 vos_mem_free(pPnoRequest);
7295
7296 EXIT();
7297 return status;
7298}
7299
7300#endif /*FEATURE_WLAN_SCAN_PNO*/
7301
7302
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007303#ifdef FEATURE_WLAN_TDLS
7304static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7305 u8 *peer, u8 action_code, u8 dialog_token,
7306 u16 status_code, const u8 *buf, size_t len)
7307{
7308
7309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7310 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007311 u8 peerMac[6];
7312 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007313 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007314 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007315 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007316
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007317 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007320 "Invalid arguments");
7321 return -EINVAL;
7322 }
7323
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007324 if (pHddCtx->isLogpInProgress)
7325 {
7326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007328 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007329 return -EBUSY;
7330 }
7331
Hoonki Lee27511902013-03-14 18:19:06 -07007332 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007333 {
Hoonki Lee27511902013-03-14 18:19:06 -07007334 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7335 "%s: TDLS mode is disabled OR not enabled in FW."
7336 MAC_ADDRESS_STR " action %d declined.",
7337 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007338 return -ENOTSUPP;
7339 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007340
Hoonki Lee27511902013-03-14 18:19:06 -07007341 /* other than teardown frame, other mgmt frames are not sent if disabled */
7342 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7343 {
7344 /* if tdls_mode is disabled to respond to peer's request */
7345 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7346 {
7347 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7348 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007349 " TDLS mode is disabled. action %d declined.",
7350 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007351
7352 return -ENOTSUPP;
7353 }
7354 }
7355
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007356 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7357 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007358 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007359 {
7360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007361 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007362 " TDLS setup is ongoing. action %d declined.",
7363 __func__, MAC_ADDR_ARRAY(peer), action_code);
7364 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007365 }
7366 }
7367
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007368 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7369 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007370 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007371 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007372 {
7373 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7374 we return error code at 'add_station()'. Hence we have this
7375 check again in addtion to add_station().
7376 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007377 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007378 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007381 " TDLS Max peer already connected. action %d declined.",
7382 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007383 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007384 }
7385 else
7386 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007387 /* maximum reached. tweak to send error code to peer and return
7388 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007389 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7391 "%s: " MAC_ADDRESS_STR
7392 " TDLS Max peer already connected send response status %d",
7393 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007394 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007395 /* fall through to send setup resp with failure status
7396 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007397 }
7398 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007399 else
7400 {
7401 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007402 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007403 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007404 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007406 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7407 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007408 return -EPERM;
7409 }
7410 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007411 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007412 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007413
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007414#ifdef WLAN_FEATURE_TDLS_DEBUG
7415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007416 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7417 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7418 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007419#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007420
Hoonki Leea34dd892013-02-05 22:56:02 -08007421 /*Except teardown responder will not be used so just make 0*/
7422 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007423 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007424 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007425
7426 hddTdlsPeer_t *pTdlsPeer;
7427 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7428
7429 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7430 responder = pTdlsPeer->is_responder;
7431 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007432 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7434 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7435 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7436 dialog_token, status_code, len);
7437 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007438 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007439 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007440
Hoonki Lee14621352013-04-16 17:51:19 -07007441 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7442 (SIR_MAC_TDLS_DIS_RSP == action_code))
7443 {
7444 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7445 {
7446 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7447 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7448 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7449 }
7450 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7451 }
7452
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007453 /* make sure doesn't call send_mgmt() while it is pending */
7454 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7455 {
7456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7457 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7458 __func__, MAC_ADDR_ARRAY(peer), action_code);
7459 return -EBUSY;
7460 }
7461
7462 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007463 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7464
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007465 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007466 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007467
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007468 if (VOS_STATUS_SUCCESS != status)
7469 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7471 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007472 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007473 wlan_hdd_tdls_check_bmps(pAdapter);
7474 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007475 }
7476
Hoonki Leed37cbb32013-04-20 00:31:14 -07007477 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7478 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7479
7480 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007481 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7483 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7484 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007485 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007486 wlan_hdd_tdls_check_bmps(pAdapter);
7487 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007488 }
7489
Gopichand Nakkala05922802013-03-14 12:23:19 -07007490 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007491 {
7492 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007493 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007494 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007495
Hoonki Leea34dd892013-02-05 22:56:02 -08007496 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7497 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007498 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007499 }
7500 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7501 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007502 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007503 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007504
7505 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007506error:
7507 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7508 because we already know that this transaction will be failed,
7509 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7510 to be safe, do not change the state mahine.
7511 */
7512 if(max_sta_failed == 0 &&
7513 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7514 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7515 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007516}
7517
7518static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7519 u8 *peer, enum nl80211_tdls_operation oper)
7520{
7521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307523 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307524#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7525 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307526 tANI_U8 staIdx;
7527#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007528#ifdef WLAN_FEATURE_TDLS_DEBUG
7529 const char *tdls_oper_str[]= {
7530 "NL80211_TDLS_DISCOVERY_REQ",
7531 "NL80211_TDLS_SETUP",
7532 "NL80211_TDLS_TEARDOWN",
7533 "NL80211_TDLS_ENABLE_LINK",
7534 "NL80211_TDLS_DISABLE_LINK",
7535 "NL80211_TDLS_UNKONW_OPER"};
7536#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007537 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007538
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007540 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007542 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007543 return -EINVAL;
7544 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307546 status = wlan_hdd_validate_context(pHddCtx);
7547
7548 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007549 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7551 "%s: HDD context is not valid", __func__);
7552 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007553 }
7554
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007555 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7556
7557 if ( NULL == pTdlsPeer ) {
7558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7559 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7560 return -EINVAL;
7561 }
7562
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007563#ifdef WLAN_FEATURE_TDLS_DEBUG
7564 if((int)oper > 4)
7565 oper = 5;
7566
7567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007568 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7569 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007570 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007571#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007572
7573 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007574 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007575 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007577 "TDLS Disabled in INI OR not enabled in FW. "
7578 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007579 return -ENOTSUPP;
7580 }
7581
7582 switch (oper) {
7583 case NL80211_TDLS_ENABLE_LINK:
7584 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007585 VOS_STATUS status;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307586 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007587
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007588 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7589 {
7590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7591 MAC_ADDRESS_STR " failed",
7592 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7593 return -EINVAL;
7594 }
7595
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007596 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007597 {
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307598 if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
7599 return -EINVAL;
7600 }
7601 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
7602
7603 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
7604 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
7605 /* Send TDLS peer UAPSD capabilities to the firmware and
7606 * register with the TL on after the response for this operation
7607 * is received .
7608 */
7609 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
7610 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
7611 if (status <= 0)
7612 {
7613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7614 "%s: Link Establish Request Faled Status %ld",
7615 __func__, status);
7616 return -EINVAL;
7617 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007618 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307619 /* Mark TDLS client Authenticated .*/
7620 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7621 pTdlsPeer->staId,
7622 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007623 if (VOS_STATUS_SUCCESS == status)
7624 {
Hoonki Lee14621352013-04-16 17:51:19 -07007625 if (pTdlsPeer->is_responder == 0)
7626 {
7627 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7628
7629 wlan_hdd_tdls_timer_restart(pAdapter,
7630 &pTdlsPeer->initiatorWaitTimeoutTimer,
7631 WAIT_TIME_TDLS_INITIATOR);
7632 /* suspend initiator TX until it receives direct packet from the
7633 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7634 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7635 &staId, NULL);
7636 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007637 wlan_hdd_tdls_increment_peer_count(pAdapter);
7638 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007639 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307640
7641 /* Update TL about the UAPSD masks , to route the packets to firmware */
7642 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7643 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VO )
7644 {
7645 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7646 pTdlsPeer->staId,
7647 WLANTL_AC_VO,
7648 7,
7649 7,
7650 0,
7651 0,
7652 WLANTL_BI_DIR );
7653
7654 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7655 }
7656
7657 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7658 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VI )
7659 {
7660 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7661 pTdlsPeer->staId,
7662 WLANTL_AC_VI,
7663 5,
7664 5,
7665 0,
7666 0,
7667 WLANTL_BI_DIR );
7668
7669 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7670 }
7671
7672 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7673 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BK )
7674 {
7675 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7676 pTdlsPeer->staId,
7677 WLANTL_AC_BK,
7678 2,
7679 2,
7680 0,
7681 0,
7682 WLANTL_BI_DIR );
7683
7684 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7685 }
7686
7687 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7688 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BE )
7689 {
7690 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7691 pTdlsPeer->staId,
7692 WLANTL_AC_BE,
7693 3,
7694 3,
7695 0,
7696 0,
7697 WLANTL_BI_DIR );
7698
7699 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7700 }
7701
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007702 }
7703
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007704 }
7705 break;
7706 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007707 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007708 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007709 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007710 long status;
7711
7712 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7713
Lee Hoonkic1262f22013-01-24 21:59:00 -08007714 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7715 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007716
7717 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7718 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7719 if (status <= 0)
7720 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007721 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7723 "%s: Del station failed status %ld",
7724 __func__, status);
7725 return -EPERM;
7726 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007727 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007728 }
7729 else
7730 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7732 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007733 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307734#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7735 if (pHddTdlsCtx->defer_link_lost_indication)
7736 {
7737 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7738 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7739 {
7740 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7741 if ( 0 != status)
7742 {
7743 hddLog(VOS_TRACE_LEVEL_ERROR,
7744 "%s wlan_hdd_disconnect failure, returned %d \n",
7745 __func__, (int)status );
7746 return -EINVAL;
7747 }
7748 }
7749 }
7750#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007751 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007752 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007753 case NL80211_TDLS_TEARDOWN:
7754 case NL80211_TDLS_SETUP:
7755 case NL80211_TDLS_DISCOVERY_REQ:
7756 /* We don't support in-driver setup/teardown/discovery */
7757 return -ENOTSUPP;
7758 default:
7759 return -ENOTSUPP;
7760 }
7761 return 0;
7762}
Chilam NG571c65a2013-01-19 12:27:36 +05307763
7764int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7765 struct net_device *dev, u8 *peer)
7766{
7767 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7768 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7769
7770 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7771 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7772}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007773#endif
7774
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307775#ifdef WLAN_FEATURE_GTK_OFFLOAD
7776/*
7777 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7778 * Callback rountine called upon receiving response for
7779 * get offload info
7780 */
7781void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7782 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7783{
7784
7785 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307786 tANI_U8 tempReplayCounter[8];
7787 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307788
7789 ENTER();
7790
7791 if (NULL == pAdapter)
7792 {
7793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7794 "%s: HDD adapter is Null", __func__);
7795 return ;
7796 }
7797
7798 if (NULL == pGtkOffloadGetInfoRsp)
7799 {
7800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7801 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7802 return ;
7803 }
7804
7805 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7806 {
7807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7808 "%s: wlan Failed to get replay counter value",
7809 __func__);
7810 return ;
7811 }
7812
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307813 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7814 /* Update replay counter */
7815 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
7816 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
7817
7818 {
7819 /* changing from little to big endian since supplicant
7820 * works on big endian format
7821 */
7822 int i;
7823 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
7824
7825 for (i = 0; i < 8; i++)
7826 {
7827 tempReplayCounter[7-i] = (tANI_U8)p[i];
7828 }
7829 }
7830
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307831 /* Update replay counter to NL */
7832 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307833 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307834}
7835
7836/*
7837 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7838 * This function is used to offload GTK rekeying job to the firmware.
7839 */
7840int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7841 struct cfg80211_gtk_rekey_data *data)
7842{
7843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7844 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7845 hdd_station_ctx_t *pHddStaCtx;
7846 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307847 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307848 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307849 eHalStatus status = eHAL_STATUS_FAILURE;
7850
7851 ENTER();
7852
7853 if (NULL == pAdapter)
7854 {
7855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7856 "%s: HDD adapter is Null", __func__);
7857 return -ENODEV;
7858 }
7859
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307860 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307861
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307862 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307863 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7865 "%s: HDD context is not valid", __func__);
7866 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307867 }
7868
7869 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7870 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7871 if (NULL == hHal)
7872 {
7873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7874 "%s: HAL context is Null!!!", __func__);
7875 return -EAGAIN;
7876 }
7877
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307878 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
7879 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
7880 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
7881 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307882 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307883 {
7884 /* changing from big to little endian since driver
7885 * works on little endian format
7886 */
7887 tANI_U8 *p =
7888 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
7889 int i;
7890
7891 for (i = 0; i < 8; i++)
7892 {
7893 p[7-i] = data->replay_ctr[i];
7894 }
7895 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307896
7897 if (TRUE == pHddCtx->hdd_wlan_suspended)
7898 {
7899 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307900 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
7901 sizeof (tSirGtkOffloadParams));
7902 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307903 pAdapter->sessionId);
7904
7905 if (eHAL_STATUS_SUCCESS != status)
7906 {
7907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7908 "%s: sme_SetGTKOffload failed, returned %d",
7909 __func__, status);
7910 return status;
7911 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7913 "%s: sme_SetGTKOffload successfull", __func__);
7914 }
7915 else
7916 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7918 "%s: wlan not suspended GTKOffload request is stored",
7919 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307920 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307921
7922 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307923}
7924#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7925
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307926/*
7927 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7928 * This function is used to set access control policy
7929 */
7930static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7931 struct net_device *dev, const struct cfg80211_acl_data *params)
7932{
7933 int i;
7934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7935 hdd_hostapd_state_t *pHostapdState;
7936 tsap_Config_t *pConfig;
7937 v_CONTEXT_t pVosContext = NULL;
7938 hdd_context_t *pHddCtx;
7939 int status;
7940
7941 ENTER();
7942
7943 if (NULL == pAdapter)
7944 {
7945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7946 "%s: HDD adapter is Null", __func__);
7947 return -ENODEV;
7948 }
7949
7950 if (NULL == params)
7951 {
7952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7953 "%s: params is Null", __func__);
7954 return -EINVAL;
7955 }
7956
7957 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7958 status = wlan_hdd_validate_context(pHddCtx);
7959
7960 if (0 != status)
7961 {
7962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7963 "%s: HDD context is not valid", __func__);
7964 return status;
7965 }
7966
7967 pVosContext = pHddCtx->pvosContext;
7968 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7969
7970 if (NULL == pHostapdState)
7971 {
7972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7973 "%s: pHostapdState is Null", __func__);
7974 return -EINVAL;
7975 }
7976
7977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7978 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7979
7980 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7981 {
7982 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7983
7984 /* default value */
7985 pConfig->num_accept_mac = 0;
7986 pConfig->num_deny_mac = 0;
7987
7988 /**
7989 * access control policy
7990 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7991 * listed in hostapd.deny file.
7992 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7993 * listed in hostapd.accept file.
7994 */
7995 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7996 {
7997 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7998 }
7999 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
8000 {
8001 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
8002 }
8003 else
8004 {
8005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8006 "%s:Acl Policy : %d is not supported",
8007 __func__, params->acl_policy);
8008 return -ENOTSUPP;
8009 }
8010
8011 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
8012 {
8013 pConfig->num_accept_mac = params->n_acl_entries;
8014 for (i = 0; i < params->n_acl_entries; i++)
8015 {
8016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8017 "** Add ACL MAC entry %i in WhiletList :"
8018 MAC_ADDRESS_STR, i,
8019 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8020
8021 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
8022 sizeof(qcmacaddr));
8023 }
8024 }
8025 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
8026 {
8027 pConfig->num_deny_mac = params->n_acl_entries;
8028 for (i = 0; i < params->n_acl_entries; i++)
8029 {
8030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8031 "** Add ACL MAC entry %i in BlackList :"
8032 MAC_ADDRESS_STR, i,
8033 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8034
8035 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
8036 sizeof(qcmacaddr));
8037 }
8038 }
8039
8040 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
8041 {
8042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8043 "%s: SAP Set Mac Acl fail", __func__);
8044 return -EINVAL;
8045 }
8046 }
8047 else
8048 {
8049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8050 "%s: Invalid device_mode = %d",
8051 __func__, pAdapter->device_mode);
8052 return -EINVAL;
8053 }
8054
8055 return 0;
8056}
8057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308059static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07008060{
8061 .add_virtual_intf = wlan_hdd_add_virtual_intf,
8062 .del_virtual_intf = wlan_hdd_del_virtual_intf,
8063 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
8064 .change_station = wlan_hdd_change_station,
8065#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8066 .add_beacon = wlan_hdd_cfg80211_add_beacon,
8067 .del_beacon = wlan_hdd_cfg80211_del_beacon,
8068 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008069#else
8070 .start_ap = wlan_hdd_cfg80211_start_ap,
8071 .change_beacon = wlan_hdd_cfg80211_change_beacon,
8072 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07008073#endif
8074 .change_bss = wlan_hdd_cfg80211_change_bss,
8075 .add_key = wlan_hdd_cfg80211_add_key,
8076 .get_key = wlan_hdd_cfg80211_get_key,
8077 .del_key = wlan_hdd_cfg80211_del_key,
8078 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008081#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 .scan = wlan_hdd_cfg80211_scan,
8083 .connect = wlan_hdd_cfg80211_connect,
8084 .disconnect = wlan_hdd_cfg80211_disconnect,
8085 .join_ibss = wlan_hdd_cfg80211_join_ibss,
8086 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
8087 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
8088 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
8089 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
8091 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
8092 .mgmt_tx = wlan_hdd_action,
8093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8094 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
8095 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
8096 .set_txq_params = wlan_hdd_set_txq_params,
8097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 .get_station = wlan_hdd_cfg80211_get_station,
8099 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
8100 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008101 .add_station = wlan_hdd_cfg80211_add_station,
8102#ifdef FEATURE_WLAN_LFR
8103 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
8104 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
8105 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
8106#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008107#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8108 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8109#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008110#ifdef FEATURE_WLAN_TDLS
8111 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8112 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8113#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308114#ifdef WLAN_FEATURE_GTK_OFFLOAD
8115 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8116#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308117#ifdef FEATURE_WLAN_SCAN_PNO
8118 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8119 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8120#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308121 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008122};
8123