blob: a833c474848c6e39c954d244642adfee4148d3f3 [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 Nakkala29149562013-05-10 21:43:41 +05303070 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3071 {
3072 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3073 WLANTL_STA_AUTHENTICATED);
3074 if (status != VOS_STATUS_SUCCESS)
3075 {
3076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3077 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3078 return -EINVAL;
3079 }
3080 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3082 "%s: TL Moving to Authenticated state", __func__);
3083 }
3084 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303085
Jeff Johnsone7245742012-09-05 17:12:55 -07003086 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003087 return status;
3088}
3089
3090/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003091 * FUNCTION: wlan_hdd_cfg80211_add_key
3092 * This function is used to initialize the key information
3093 */
3094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003095static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 struct net_device *ndev,
3097 u8 key_index, bool pairwise,
3098 const u8 *mac_addr,
3099 struct key_params *params
3100 )
3101#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 struct net_device *ndev,
3104 u8 key_index, const u8 *mac_addr,
3105 struct key_params *params
3106 )
3107#endif
3108{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003110 tCsrRoamSetKey setKey;
3111 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303112 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003113 v_U32_t roamId= 0xFF;
3114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003115 hdd_hostapd_state_t *pHostapdState;
3116 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003117 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303118 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 ENTER();
3121
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303122 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3123 status = wlan_hdd_validate_context(pHddCtx);
3124
3125 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003126 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "%s: HDD context is not valid", __func__);
3129 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003130 }
3131
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003132 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3133 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003134
3135 if (CSR_MAX_NUM_KEY <= key_index)
3136 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 key_index);
3139
3140 return -EINVAL;
3141 }
3142
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003143 if (CSR_MAX_KEY_LEN < params->key_len)
3144 {
3145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3146 params->key_len);
3147
3148 return -EINVAL;
3149 }
3150
3151 hddLog(VOS_TRACE_LEVEL_INFO,
3152 "%s: called with key index = %d & key length %d",
3153 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003154
3155 /*extract key idx, key len and key*/
3156 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3157 setKey.keyId = key_index;
3158 setKey.keyLength = params->key_len;
3159 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3160
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003161 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003162 {
3163 case WLAN_CIPHER_SUITE_WEP40:
3164 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3165 break;
3166
3167 case WLAN_CIPHER_SUITE_WEP104:
3168 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3169 break;
3170
3171 case WLAN_CIPHER_SUITE_TKIP:
3172 {
3173 u8 *pKey = &setKey.Key[0];
3174 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3175
3176 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3177
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003178 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003179
3180 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003181 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003182 |--------------|----------|----------|
3183 <---16bytes---><--8bytes--><--8bytes-->
3184
3185 */
3186 /*Sme expects the 32 bytes key to be in the below order
3187
3188 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003189 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003190 |--------------|----------|----------|
3191 <---16bytes---><--8bytes--><--8bytes-->
3192 */
3193 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003194 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003195
3196 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003197 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003198
3199 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003200 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003201
3202
3203 break;
3204 }
3205
3206 case WLAN_CIPHER_SUITE_CCMP:
3207 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3208 break;
3209
3210#ifdef FEATURE_WLAN_WAPI
3211 case WLAN_CIPHER_SUITE_SMS4:
3212 {
3213 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3214 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3215 params->key, params->key_len);
3216 return 0;
3217 }
3218#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003219
Jeff Johnson295189b2012-06-20 16:38:30 -07003220#ifdef FEATURE_WLAN_CCX
3221 case WLAN_CIPHER_SUITE_KRK:
3222 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3223 break;
3224#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003225
3226#ifdef WLAN_FEATURE_11W
3227 case WLAN_CIPHER_SUITE_AES_CMAC:
3228 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003229 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003230#endif
3231
Jeff Johnson295189b2012-06-20 16:38:30 -07003232 default:
3233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3234 __func__, params->cipher);
3235 return -EOPNOTSUPP;
3236 }
3237
3238 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3239 __func__, setKey.encType);
3240
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003241 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3243 (!pairwise)
3244#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003245 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003246#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003247 )
3248 {
3249 /* set group key*/
3250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3251 "%s- %d: setting Broadcast key",
3252 __func__, __LINE__);
3253 setKey.keyDirection = eSIR_RX_ONLY;
3254 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3255 }
3256 else
3257 {
3258 /* set pairwise key*/
3259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3260 "%s- %d: setting pairwise key",
3261 __func__, __LINE__);
3262 setKey.keyDirection = eSIR_TX_RX;
3263 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3264 }
3265 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3266 {
3267 setKey.keyDirection = eSIR_TX_RX;
3268 /*Set the group key*/
3269 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3270 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003271
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003272 if ( 0 != status )
3273 {
3274 hddLog(VOS_TRACE_LEVEL_ERROR,
3275 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3276 return -EINVAL;
3277 }
3278 /*Save the keys here and call sme_RoamSetKey for setting
3279 the PTK after peer joins the IBSS network*/
3280 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3281 &setKey, sizeof(tCsrRoamSetKey));
3282 return status;
3283 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303284 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3285 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3286 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003287 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003288 if( pHostapdState->bssState == BSS_START )
3289 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003290 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3291
3292 if ( status != eHAL_STATUS_SUCCESS )
3293 {
3294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3295 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3296 __LINE__, status );
3297 }
3298 }
3299
3300 /* Saving WEP keys */
3301 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3302 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3303 {
3304 //Save the wep key in ap context. Issue setkey after the BSS is started.
3305 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3306 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3307 }
3308 else
3309 {
3310 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003311 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003312 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3313 }
3314 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003315 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3316 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003317 {
3318 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3319 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3320
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303321#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3322 if (!pairwise)
3323#else
3324 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3325#endif
3326 {
3327 /* set group key*/
3328 if (pHddStaCtx->roam_info.deferKeyComplete)
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3331 "%s- %d: Perform Set key Complete",
3332 __func__, __LINE__);
3333 hdd_PerformRoamSetKeyComplete(pAdapter);
3334 }
3335 }
3336
Jeff Johnson295189b2012-06-20 16:38:30 -07003337 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3338
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003339 pWextState->roamProfile.Keys.defaultIndex = key_index;
3340
3341
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003342 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003343 params->key, params->key_len);
3344
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303345
Jeff Johnson295189b2012-06-20 16:38:30 -07003346 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3347
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303348 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003349 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303350 __func__, setKey.peerMac[0], setKey.peerMac[1],
3351 setKey.peerMac[2], setKey.peerMac[3],
3352 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003353 setKey.keyDirection);
3354
3355 vos_status = wlan_hdd_check_ula_done(pAdapter);
3356
3357 if ( vos_status != VOS_STATUS_SUCCESS )
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3361 __LINE__, vos_status );
3362
3363 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3364
3365 return -EINVAL;
3366
3367 }
3368
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003369#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303370 /* The supplicant may attempt to set the PTK once pre-authentication
3371 is done. Save the key in the UMAC and include it in the ADD BSS
3372 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003373 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303374 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003375 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303376 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3377 "%s: Update PreAuth Key success", __func__);
3378 return 0;
3379 }
3380 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3381 {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303384 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003385 }
3386#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003387
3388 /* issue set key request to SME*/
3389 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3390 pAdapter->sessionId, &setKey, &roamId );
3391
3392 if ( 0 != status )
3393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303394 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3396 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3397 return -EINVAL;
3398 }
3399
3400
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303401 /* in case of IBSS as there was no information available about WEP keys during
3402 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003403 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303404 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3405 !( ( IW_AUTH_KEY_MGMT_802_1X
3406 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003407 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3408 )
3409 &&
3410 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3411 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3412 )
3413 )
3414 {
3415 setKey.keyDirection = eSIR_RX_ONLY;
3416 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3417
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303418 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003419 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303420 __func__, setKey.peerMac[0], setKey.peerMac[1],
3421 setKey.peerMac[2], setKey.peerMac[3],
3422 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003423 setKey.keyDirection);
3424
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303425 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003426 pAdapter->sessionId, &setKey, &roamId );
3427
3428 if ( 0 != status )
3429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303430 hddLog(VOS_TRACE_LEVEL_ERROR,
3431 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003432 __func__, status);
3433 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3434 return -EINVAL;
3435 }
3436 }
3437 }
3438
3439 return 0;
3440}
3441
3442/*
3443 * FUNCTION: wlan_hdd_cfg80211_get_key
3444 * This function is used to get the key information
3445 */
3446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303447static int wlan_hdd_cfg80211_get_key(
3448 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303450 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003451 const u8 *mac_addr, void *cookie,
3452 void (*callback)(void *cookie, struct key_params*)
3453 )
3454#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303455static int wlan_hdd_cfg80211_get_key(
3456 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003457 struct net_device *ndev,
3458 u8 key_index, const u8 *mac_addr, void *cookie,
3459 void (*callback)(void *cookie, struct key_params*)
3460 )
3461#endif
3462{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003464 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3465 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3466 struct key_params params;
3467
3468 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303469
Jeff Johnson295189b2012-06-20 16:38:30 -07003470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3471 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303472
Jeff Johnson295189b2012-06-20 16:38:30 -07003473 memset(&params, 0, sizeof(params));
3474
3475 if (CSR_MAX_NUM_KEY <= key_index)
3476 {
3477 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003479
3480 switch(pRoamProfile->EncryptionType.encryptionType[0])
3481 {
3482 case eCSR_ENCRYPT_TYPE_NONE:
3483 params.cipher = IW_AUTH_CIPHER_NONE;
3484 break;
3485
3486 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3487 case eCSR_ENCRYPT_TYPE_WEP40:
3488 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3489 break;
3490
3491 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3492 case eCSR_ENCRYPT_TYPE_WEP104:
3493 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3494 break;
3495
3496 case eCSR_ENCRYPT_TYPE_TKIP:
3497 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3498 break;
3499
3500 case eCSR_ENCRYPT_TYPE_AES:
3501 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3502 break;
3503
3504 default:
3505 params.cipher = IW_AUTH_CIPHER_NONE;
3506 break;
3507 }
3508
3509 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3510 params.seq_len = 0;
3511 params.seq = NULL;
3512 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3513 callback(cookie, &params);
3514 return 0;
3515}
3516
3517/*
3518 * FUNCTION: wlan_hdd_cfg80211_del_key
3519 * This function is used to delete the key information
3520 */
3521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303522static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003523 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524 u8 key_index,
3525 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 const u8 *mac_addr
3527 )
3528#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303529static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003530 struct net_device *ndev,
3531 u8 key_index,
3532 const u8 *mac_addr
3533 )
3534#endif
3535{
3536 int status = 0;
3537
3538 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303539 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003540 //it is observed that this is invalidating peer
3541 //key index whenever re-key is done. This is affecting data link.
3542 //It should be ok to ignore del_key.
3543#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3545 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3547 tCsrRoamSetKey setKey;
3548 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303549
Jeff Johnson295189b2012-06-20 16:38:30 -07003550 ENTER();
3551
3552 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3553 __func__,pAdapter->device_mode);
3554
3555 if (CSR_MAX_NUM_KEY <= key_index)
3556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003558 key_index);
3559
3560 return -EINVAL;
3561 }
3562
3563 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3564 setKey.keyId = key_index;
3565
3566 if (mac_addr)
3567 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3568 else
3569 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3570
3571 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3572
3573 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003574 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303575 )
3576 {
3577
3578 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3580 if( pHostapdState->bssState == BSS_START)
3581 {
3582 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303583
Jeff Johnson295189b2012-06-20 16:38:30 -07003584 if ( status != eHAL_STATUS_SUCCESS )
3585 {
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3588 __LINE__, status );
3589 }
3590 }
3591 }
3592 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303593 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 )
3595 {
3596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3597
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3599
3600 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003601 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303602 __func__, setKey.peerMac[0], setKey.peerMac[1],
3603 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303605 if(pAdapter->sessionCtx.station.conn_info.connState ==
3606 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303608 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003609 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303610
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 if ( 0 != status )
3612 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303613 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003614 "%s: sme_RoamSetKey failure, returned %d",
3615 __func__, status);
3616 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3617 return -EINVAL;
3618 }
3619 }
3620 }
3621#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003622 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003623 return status;
3624}
3625
3626/*
3627 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3628 * This function is used to set the default tx key index
3629 */
3630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3631static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3632 struct net_device *ndev,
3633 u8 key_index,
3634 bool unicast, bool multicast)
3635#else
3636static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3637 struct net_device *ndev,
3638 u8 key_index)
3639#endif
3640{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303642 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303643 hdd_wext_state_t *pWextState;
3644 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303645 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003646
3647 ENTER();
3648
Gopichand Nakkala29149562013-05-10 21:43:41 +05303649 if ((NULL == pAdapter))
3650 {
3651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3652 "invalid adapter");
3653 return -EINVAL;
3654 }
3655
3656 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3657 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3658
3659 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3660 {
3661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3662 "invalid Wext state or HDD context");
3663 return -EINVAL;
3664 }
3665
Jeff Johnson295189b2012-06-20 16:38:30 -07003666 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3667 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303668
Jeff Johnson295189b2012-06-20 16:38:30 -07003669 if (CSR_MAX_NUM_KEY <= key_index)
3670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 key_index);
3673
3674 return -EINVAL;
3675 }
3676
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3678 status = wlan_hdd_validate_context(pHddCtx);
3679
3680 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003681 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 "%s: HDD context is not valid", __func__);
3684 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003685 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303686
Jeff Johnson295189b2012-06-20 16:38:30 -07003687 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003688 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303689 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303691 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303693 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003694 pWextState->roamProfile.EncryptionType.encryptionType[0])
3695 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696 {
3697 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303699
Jeff Johnson295189b2012-06-20 16:38:30 -07003700 tCsrRoamSetKey setKey;
3701 v_U32_t roamId= 0xFF;
3702 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703
3704 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003705 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 Keys->defaultIndex = (u8)key_index;
3708 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3709 setKey.keyId = key_index;
3710 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303711
3712 vos_mem_copy(&setKey.Key[0],
3713 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003714 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303715
Gopichand Nakkala29149562013-05-10 21:43:41 +05303716 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303717
3718 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003719 &pHddStaCtx->conn_info.bssId[0],
3720 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721
Gopichand Nakkala29149562013-05-10 21:43:41 +05303722 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3723 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3724 eCSR_ENCRYPT_TYPE_WEP104)
3725 {
3726 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3727 even though ap is configured for WEP-40 encryption. In this canse the key length
3728 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3729 type(104) and switching encryption type to 40*/
3730 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3731 eCSR_ENCRYPT_TYPE_WEP40;
3732 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3733 eCSR_ENCRYPT_TYPE_WEP40;
3734 }
3735
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303736 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003737 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303738
Jeff Johnson295189b2012-06-20 16:38:30 -07003739 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303740 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303742
Jeff Johnson295189b2012-06-20 16:38:30 -07003743 if ( 0 != status )
3744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303745 hddLog(VOS_TRACE_LEVEL_ERROR,
3746 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 status);
3748 return -EINVAL;
3749 }
3750 }
3751 }
3752
3753 /* In SoftAp mode setting key direction for default mode */
3754 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3755 {
3756 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3757 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3758 (eCSR_ENCRYPT_TYPE_AES !=
3759 pWextState->roamProfile.EncryptionType.encryptionType[0])
3760 )
3761 {
3762 /* Saving key direction for default key index to TX default */
3763 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3764 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3765 }
3766 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303767
Jeff Johnson295189b2012-06-20 16:38:30 -07003768 return status;
3769}
3770
Jeff Johnson295189b2012-06-20 16:38:30 -07003771/*
3772 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3773 * This function is used to inform the BSS details to nl80211 interface.
3774 */
3775static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3776 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3777{
3778 struct net_device *dev = pAdapter->dev;
3779 struct wireless_dev *wdev = dev->ieee80211_ptr;
3780 struct wiphy *wiphy = wdev->wiphy;
3781 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3782 int chan_no;
3783 int ie_length;
3784 const char *ie;
3785 unsigned int freq;
3786 struct ieee80211_channel *chan;
3787 int rssi = 0;
3788 struct cfg80211_bss *bss = NULL;
3789
3790 ENTER();
3791
3792 if( NULL == pBssDesc )
3793 {
3794 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3795 return bss;
3796 }
3797
3798 chan_no = pBssDesc->channelId;
3799 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3800 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3801
3802 if( NULL == ie )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3805 return bss;
3806 }
3807
3808#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3809 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3810 {
3811 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3812 }
3813 else
3814 {
3815 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3816 }
3817#else
3818 freq = ieee80211_channel_to_frequency(chan_no);
3819#endif
3820
3821 chan = __ieee80211_get_channel(wiphy, freq);
3822
3823 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3824 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3825 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3826 if (bss == NULL)
3827 {
3828 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3829
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303830 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3831 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003832 pBssDesc->capabilityInfo,
3833 pBssDesc->beaconInterval, ie, ie_length,
3834 rssi, GFP_KERNEL ));
3835}
3836 else
3837 {
3838 return bss;
3839 }
3840}
3841
3842
3843
3844/*
3845 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3846 * This function is used to inform the BSS details to nl80211 interface.
3847 */
3848struct cfg80211_bss*
3849wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3850 tSirBssDescription *bss_desc
3851 )
3852{
3853 /*
3854 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3855 already exists in bss data base of cfg80211 for that particular BSS ID.
3856 Using cfg80211_inform_bss_frame to update the bss entry instead of
3857 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3858 now there is no possibility to get the mgmt(probe response) frame from PE,
3859 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3860 cfg80211_inform_bss_frame.
3861 */
3862 struct net_device *dev = pAdapter->dev;
3863 struct wireless_dev *wdev = dev->ieee80211_ptr;
3864 struct wiphy *wiphy = wdev->wiphy;
3865 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003866#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3867 qcom_ie_age *qie_age = NULL;
3868 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3869#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003871#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003872 const char *ie =
3873 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3874 unsigned int freq;
3875 struct ieee80211_channel *chan;
3876 struct ieee80211_mgmt *mgmt =
3877 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3878 struct cfg80211_bss *bss_status = NULL;
3879 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3880 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003881#ifdef WLAN_OPEN_SOURCE
3882 struct timespec ts;
3883#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003884
3885 ENTER();
3886
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003887 if (!mgmt)
3888 return NULL;
3889
Jeff Johnson295189b2012-06-20 16:38:30 -07003890 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003891
3892#ifdef WLAN_OPEN_SOURCE
3893 /* Android does not want the timestamp from the frame.
3894 Instead it wants a monotonic increasing value */
3895 get_monotonic_boottime(&ts);
3896 mgmt->u.probe_resp.timestamp =
3897 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3898#else
3899 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003900 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3901 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003902
3903#endif
3904
Jeff Johnson295189b2012-06-20 16:38:30 -07003905 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3906 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003907
3908#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3909 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3910 /* Assuming this is the last IE, copy at the end */
3911 ie_length -=sizeof(qcom_ie_age);
3912 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3913 qie_age->element_id = QCOM_VENDOR_IE_ID;
3914 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3915 qie_age->oui_1 = QCOM_OUI1;
3916 qie_age->oui_2 = QCOM_OUI2;
3917 qie_age->oui_3 = QCOM_OUI3;
3918 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3919 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3920#endif
3921
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303923 if (bss_desc->fProbeRsp)
3924 {
3925 mgmt->frame_control |=
3926 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3927 }
3928 else
3929 {
3930 mgmt->frame_control |=
3931 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003933
3934#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303935 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003936 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3937 {
3938 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3939 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303940 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003941 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3942
3943 {
3944 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3945 }
3946 else
3947 {
3948 kfree(mgmt);
3949 return NULL;
3950 }
3951#else
3952 freq = ieee80211_channel_to_frequency(chan_no);
3953#endif
3954 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003955 /*when the band is changed on the fly using the GUI, three things are done
3956 * 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)
3957 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3958 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3959 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3960 * and discards the channels correponding to previous band and calls back with zero bss results.
3961 * 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
3962 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3963 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3964 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3965 * So drop the bss and continue to next bss.
3966 */
3967 if(chan == NULL)
3968 {
3969 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003970 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003971 return NULL;
3972 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303974 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003975 * */
3976 if (( eConnectionState_Associated ==
3977 pAdapter->sessionCtx.station.conn_info.connState ) &&
3978 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3979 pAdapter->sessionCtx.station.conn_info.bssId,
3980 WNI_CFG_BSSID_LEN)))
3981 {
3982 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3983 rssi = (pAdapter->rssi * 100);
3984 }
3985 else
3986 {
3987 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3988 }
3989
3990 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3991 frame_len, rssi, GFP_KERNEL);
3992 kfree(mgmt);
3993 return bss_status;
3994}
3995
3996/*
3997 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3998 * This function is used to update the BSS data base of CFG8011
3999 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304000struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 tCsrRoamInfo *pRoamInfo
4002 )
4003{
4004 tCsrRoamConnectedProfile roamProfile;
4005 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4006 struct cfg80211_bss *bss = NULL;
4007
4008 ENTER();
4009
4010 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4011 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4012
4013 if (NULL != roamProfile.pBssDesc)
4014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 &roamProfile);
4017
4018 if (NULL == bss)
4019 {
4020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4021 __func__);
4022 }
4023
4024 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4025 }
4026 else
4027 {
4028 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4029 __func__);
4030 }
4031 return bss;
4032}
4033
4034/*
4035 * FUNCTION: wlan_hdd_cfg80211_update_bss
4036 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304037static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4038 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004039 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304040{
Jeff Johnson295189b2012-06-20 16:38:30 -07004041 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4042 tCsrScanResultInfo *pScanResult;
4043 eHalStatus status = 0;
4044 tScanResultHandle pResult;
4045 struct cfg80211_bss *bss_status = NULL;
4046
4047 ENTER();
4048
4049 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4050 {
4051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4052 return -EAGAIN;
4053 }
4054
4055 /*
4056 * start getting scan results and populate cgf80211 BSS database
4057 */
4058 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4059
4060 /* no scan results */
4061 if (NULL == pResult)
4062 {
4063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4064 return status;
4065 }
4066
4067 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4068
4069 while (pScanResult)
4070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 /*
4072 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4073 * entry already exists in bss data base of cfg80211 for that
4074 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4075 * bss entry instead of cfg80211_inform_bss, But this call expects
4076 * mgmt packet as input. As of now there is no possibility to get
4077 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004078 * ieee80211_mgmt(probe response) and passing to c
4079 * fg80211_inform_bss_frame.
4080 * */
4081
4082 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4083 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304084
Jeff Johnson295189b2012-06-20 16:38:30 -07004085
4086 if (NULL == bss_status)
4087 {
4088 hddLog(VOS_TRACE_LEVEL_INFO,
4089 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4090 }
4091 else
4092 {
4093 cfg80211_put_bss(bss_status);
4094 }
4095
4096 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4097 }
4098
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304099 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004100
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304101 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004102}
4103
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004104void
4105hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4106{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004108 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4109 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4110 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004111} /****** end hddPrintMacAddr() ******/
4112
4113void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004114hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004115{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304116 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004117 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4118 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4119 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4120 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004121} /****** end hddPrintPmkId() ******/
4122
4123//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4124//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4125
4126//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4127//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4128
4129#define dump_bssid(bssid) \
4130 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004131 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4132 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4133 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004134 }
4135
4136#define dump_pmkid(pMac, pmkid) \
4137 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004138 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4139 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4140 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004141 }
4142
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004143#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004144/*
4145 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4146 * This function is used to notify the supplicant of a new PMKSA candidate.
4147 */
4148int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004150 int index, bool preauth )
4151{
Jeff Johnsone7245742012-09-05 17:12:55 -07004152#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004153 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004154 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004155
4156 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004157 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004158
4159 if( NULL == pRoamInfo )
4160 {
4161 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4162 return -EINVAL;
4163 }
4164
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004165 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4166 {
4167 dump_bssid(pRoamInfo->bssid);
4168 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004169 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004170 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004171#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004173}
4174#endif //FEATURE_WLAN_LFR
4175
Jeff Johnson295189b2012-06-20 16:38:30 -07004176/*
4177 * FUNCTION: hdd_cfg80211_scan_done_callback
4178 * scanning callback function, called after finishing scan
4179 *
4180 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4183{
4184 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304185 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4188 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004189 struct cfg80211_scan_request *req = NULL;
4190 int ret = 0;
4191
4192 ENTER();
4193
4194 hddLog(VOS_TRACE_LEVEL_INFO,
4195 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304196 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 __func__, halHandle, pContext, (int) scanId, (int) status);
4198
4199 //Block on scan req completion variable. Can't wait forever though.
4200 ret = wait_for_completion_interruptible_timeout(
4201 &pScanInfo->scan_req_completion_event,
4202 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4203 if (!ret)
4204 {
4205 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004206 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 }
4208
4209 if(pScanInfo->mScanPending != VOS_TRUE)
4210 {
4211 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004212 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 }
4214
4215 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004217 {
4218 hddLog(VOS_TRACE_LEVEL_INFO,
4219 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304220 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004221 (int) scanId);
4222 }
4223
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304224 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 pAdapter);
4226
4227 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004229
4230
4231 /* If any client wait scan result through WEXT
4232 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004233 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 {
4235 /* The other scan request waiting for current scan finish
4236 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004237 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004238 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004239 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004240 }
4241 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004242 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004243 {
4244 struct net_device *dev = pAdapter->dev;
4245 union iwreq_data wrqu;
4246 int we_event;
4247 char *msg;
4248
4249 memset(&wrqu, '\0', sizeof(wrqu));
4250 we_event = SIOCGIWSCAN;
4251 msg = NULL;
4252 wireless_send_event(dev, we_event, &wrqu, msg);
4253 }
4254 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004255 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004256
4257 /* Get the Scan Req */
4258 req = pAdapter->request;
4259
4260 if (!req)
4261 {
4262 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004263 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004264 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 }
4266
4267 /*
4268 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304269 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004270 req->n_ssids = 0;
4271 req->n_channels = 0;
4272 req->ie = 0;
4273
Jeff Johnson295189b2012-06-20 16:38:30 -07004274 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004275 /* Scan is no longer pending */
4276 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004277
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004278 /*
4279 * cfg80211_scan_done informing NL80211 about completion
4280 * of scanning
4281 */
4282 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004283 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004284
Jeff Johnsone7245742012-09-05 17:12:55 -07004285allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004286 /* release the wake lock at the end of the scan*/
4287 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004288
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004289 /* Acquire wakelock to handle the case where APP's tries to suspend
4290 * immediatly after the driver gets connect request(i.e after scan)
4291 * from supplicant, this result in app's is suspending and not able
4292 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004293 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004294
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004295#ifdef FEATURE_WLAN_TDLS
4296 wlan_hdd_tdls_scan_done_callback(pAdapter);
4297#endif
4298
Jeff Johnson295189b2012-06-20 16:38:30 -07004299 EXIT();
4300 return 0;
4301}
4302
4303/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004304 * FUNCTION: hdd_isScanAllowed
4305 * Go through each adapter and check if scan allowed
4306 *
4307 */
4308v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4309{
4310 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4311 hdd_station_ctx_t *pHddStaCtx = NULL;
4312 hdd_adapter_t *pAdapter = NULL;
4313 VOS_STATUS status = 0;
4314 v_U8_t staId = 0;
4315 v_U8_t *staMac = NULL;
4316
4317 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4318
4319 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4320 {
4321 pAdapter = pAdapterNode->pAdapter;
4322
4323 if( pAdapter )
4324 {
4325 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304326 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004327 __func__, pAdapter->device_mode);
4328 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4329 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4330 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4331 {
4332 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4333 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4334 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4335 {
4336 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304339 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004340 staMac[0], staMac[1], staMac[2],
4341 staMac[3], staMac[4], staMac[5]);
4342 return VOS_FALSE;
4343 }
4344 }
4345 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4346 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4347 {
4348 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4349 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304350 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004351 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4352 {
4353 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4354
4355 hddLog(VOS_TRACE_LEVEL_ERROR,
4356 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304357 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004358 staMac[0], staMac[1], staMac[2],
4359 staMac[3], staMac[4], staMac[5]);
4360 return VOS_FALSE;
4361 }
4362 }
4363 }
4364 }
4365 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4366 pAdapterNode = pNext;
4367 }
4368 hddLog(VOS_TRACE_LEVEL_INFO,
4369 "%s: Scan allowed", __func__);
4370 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304371}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004372
4373/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 * FUNCTION: wlan_hdd_cfg80211_scan
4375 * this scan respond to scan trigger and update cfg80211 scan database
4376 * later, scan dump command can be used to recieve scan results
4377 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004378int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4379#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4380 struct net_device *dev,
4381#endif
4382 struct cfg80211_scan_request *request)
4383{
4384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4385 struct net_device *dev = request->wdev->netdev;
4386#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304387 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004388 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4389 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304390 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004391 tCsrScanRequest scanRequest;
4392 tANI_U8 *channelList = NULL, i;
4393 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304394 int status;
4395 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004396 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004397
4398 ENTER();
4399
4400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4401 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004402
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304403 status = wlan_hdd_validate_context(pHddCtx);
4404
4405 if (0 != status)
4406 {
4407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4408 "%s: HDD context is not valid", __func__);
4409 return status;
4410 }
4411
4412 cfg_param = pHddCtx->cfg_ini;
4413 pScanInfo = &pHddCtx->scan_info;
4414
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004415 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004416 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004417 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004418 {
4419 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004420 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4421 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004422 return -EBUSY;
4423 }
4424
Jeff Johnson295189b2012-06-20 16:38:30 -07004425#ifdef WLAN_BTAMP_FEATURE
4426 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004427 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004428 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004429 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 "%s: No scanning when AMP is on", __func__);
4431 return -EOPNOTSUPP;
4432 }
4433#endif
4434 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004435 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004436 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004437 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004438 "%s: Not scanning on device_mode = %d",
4439 __func__, pAdapter->device_mode);
4440 return -EOPNOTSUPP;
4441 }
4442
4443 if (TRUE == pScanInfo->mScanPending)
4444 {
4445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004446 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004447 }
4448
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304449 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004450 //Channel and action frame is pending
4451 //Otherwise Cancel Remain On Channel and allow Scan
4452 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004453 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004454 {
4455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4456 return -EBUSY;
4457 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004458#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004459 /* if tdls disagree scan right now, return immediately.
4460 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4461 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4462 */
4463 status = wlan_hdd_tdls_scan_callback (pAdapter,
4464 wiphy,
4465#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4466 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004467#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004468 request);
4469 if(status <= 0)
4470 {
4471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4472 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004473 }
4474#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004475
Jeff Johnson295189b2012-06-20 16:38:30 -07004476 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4477 {
4478 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004479 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004482 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4483 {
4484 hddLog(VOS_TRACE_LEVEL_WARN,
4485 "%s: MAX TM Level Scan not allowed", __func__);
4486 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304487 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 }
4489 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4490
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004491 /* Check if scan is allowed at this point of time.
4492 */
4493 if (!hdd_isScanAllowed(pHddCtx))
4494 {
4495 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4496 return -EBUSY;
4497 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304498
Jeff Johnson295189b2012-06-20 16:38:30 -07004499 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4500
4501 if (NULL != request)
4502 {
4503 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304504 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004505
4506 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4507 * Becasue of this, driver is assuming that this is not wildcard scan and so
4508 * is not aging out the scan results.
4509 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004510 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 {
4512 request->n_ssids = 0;
4513 }
4514
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004515 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004516 {
4517 tCsrSSIDInfo *SsidInfo;
4518 int j;
4519 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4520 /* Allocate num_ssid tCsrSSIDInfo structure */
4521 SsidInfo = scanRequest.SSIDs.SSIDList =
4522 ( tCsrSSIDInfo *)vos_mem_malloc(
4523 request->n_ssids*sizeof(tCsrSSIDInfo));
4524
4525 if(NULL == scanRequest.SSIDs.SSIDList)
4526 {
4527 hddLog(VOS_TRACE_LEVEL_ERROR,
4528 "memory alloc failed SSIDInfo buffer");
4529 return -ENOMEM;
4530 }
4531
4532 /* copy all the ssid's and their length */
4533 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4534 {
4535 /* get the ssid length */
4536 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4537 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4538 SsidInfo->SSID.length);
4539 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4540 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4541 j, SsidInfo->SSID.ssId);
4542 }
4543 /* set the scan type to active */
4544 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4545 }
4546 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4547 {
4548 /* set the scan type to active */
4549 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4550 }
4551 else
4552 {
4553 /*Set the scan type to default type, in this case it is ACTIVE*/
4554 scanRequest.scanType = pScanInfo->scan_mode;
4555 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304556 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004557 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4558 }
4559 else
4560 {
4561 /* set the scan type to active */
4562 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4563 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4564
4565 /* set min and max channel time to zero */
4566 scanRequest.minChnTime = 0;
4567 scanRequest.maxChnTime = 0;
4568 }
4569
4570 /* set BSSType to default type */
4571 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4572
4573 /*TODO: scan the requested channels only*/
4574
4575 /*Right now scanning all the channels */
4576 if( request )
4577 {
4578 if( request->n_channels )
4579 {
4580 channelList = vos_mem_malloc( request->n_channels );
4581 if( NULL == channelList )
4582 {
4583 status = -ENOMEM;
4584 goto free_mem;
4585 }
4586
4587 for( i = 0 ; i < request->n_channels ; i++ )
4588 channelList[i] = request->channels[i]->hw_value;
4589 }
4590
4591 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4592 scanRequest.ChannelInfo.ChannelList = channelList;
4593
4594 /* set requestType to full scan */
4595 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304596
4597 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004598 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304599 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004600 */
4601
4602 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304603 * and in that case driver shoudnt flush scan results. If
4604 * driver flushes the scan results here and unfortunately if
4605 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004606 * fails which is not desired
4607 */
4608
4609 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4610 {
4611 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4612 pAdapter->sessionId );
4613 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004614
4615 if( request->ie_len )
4616 {
4617 /* save this for future association (join requires this) */
4618 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4619 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4620 pScanInfo->scanAddIE.length = request->ie_len;
4621
4622 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004623 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4624 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004625 )
4626 {
4627 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4628 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4629 }
4630
4631 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4632 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4633
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4635 request->ie_len);
4636 if (pP2pIe != NULL)
4637 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004638#ifdef WLAN_FEATURE_P2P_DEBUG
4639 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4640 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4641 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4642 {
4643 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4644 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4645 "Go nego completed to Connection is started");
4646 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4647 "for 8way Handshake");
4648 }
4649 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4650 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4651 {
4652 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4653 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4654 "Disconnected state to Connection is started");
4655 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4656 "for 4way Handshake");
4657 }
4658#endif
4659
Jeff Johnsone7245742012-09-05 17:12:55 -07004660 /* no_cck will be set during p2p find to disable 11b rates */
4661 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004662 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 hddLog(VOS_TRACE_LEVEL_INFO,
4664 "%s: This is a P2P Search", __func__);
4665 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004666
Jeff Johnsone7245742012-09-05 17:12:55 -07004667 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4668 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004669 /* set requestType to P2P Discovery */
4670 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004671 }
4672
4673 /*
4674 Skip Dfs Channel in case of P2P Search
4675 if it is set in ini file
4676 */
4677 if(cfg_param->skipDfsChnlInP2pSearch)
4678 {
4679 scanRequest.skipDfsChnlInP2pSearch = 1;
4680 }
4681 else
4682 {
4683 scanRequest.skipDfsChnlInP2pSearch = 0;
4684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004685
Jeff Johnson295189b2012-06-20 16:38:30 -07004686 }
4687 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004688 }
4689 }
4690
4691 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4692
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004693 /* acquire the wakelock to avoid the apps suspend during the scan. To
4694 * address the following issues.
4695 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4696 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4697 * for long time, this result in apps running at full power for long time.
4698 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4699 * be stuck in full power because of resume BMPS
4700 */
4701 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004702
4703 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004704 pAdapter->sessionId, &scanRequest, &scanId,
4705 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004706
Jeff Johnson295189b2012-06-20 16:38:30 -07004707 if (eHAL_STATUS_SUCCESS != status)
4708 {
4709 hddLog(VOS_TRACE_LEVEL_ERROR,
4710 "%s: sme_ScanRequest returned error %d", __func__, status);
4711 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004712 if(eHAL_STATUS_RESOURCES == status)
4713 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004714 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 -07004715 status = -EBUSY;
4716 } else {
4717 status = -EIO;
4718 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004719 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 goto free_mem;
4721 }
4722
4723 pScanInfo->mScanPending = TRUE;
4724 pAdapter->request = request;
4725 pScanInfo->scanId = scanId;
4726
4727 complete(&pScanInfo->scan_req_completion_event);
4728
4729free_mem:
4730 if( scanRequest.SSIDs.SSIDList )
4731 {
4732 vos_mem_free(scanRequest.SSIDs.SSIDList);
4733 }
4734
4735 if( channelList )
4736 vos_mem_free( channelList );
4737
4738 EXIT();
4739
4740 return status;
4741}
4742
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004743
4744void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4745{
4746 v_U8_t iniDot11Mode =
4747 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4748 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4749
4750 switch ( iniDot11Mode )
4751 {
4752 case eHDD_DOT11_MODE_AUTO:
4753 case eHDD_DOT11_MODE_11ac:
4754 case eHDD_DOT11_MODE_11ac_ONLY:
4755#ifdef WLAN_FEATURE_11AC
4756 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4757#else
4758 hddDot11Mode = eHDD_DOT11_MODE_11n;
4759#endif
4760 break;
4761 case eHDD_DOT11_MODE_11n:
4762 case eHDD_DOT11_MODE_11n_ONLY:
4763 hddDot11Mode = eHDD_DOT11_MODE_11n;
4764 break;
4765 default:
4766 hddDot11Mode = iniDot11Mode;
4767 break;
4768 }
4769 /* This call decides required channel bonding mode */
4770 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4771 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4772 operationChannel);
4773}
4774
Jeff Johnson295189b2012-06-20 16:38:30 -07004775/*
4776 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304777 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304779int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004780 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004781{
4782 int status = 0;
4783 hdd_wext_state_t *pWextState;
4784 v_U32_t roamId;
4785 tCsrRoamProfile *pRoamProfile;
4786 eMib_dot11DesiredBssType connectedBssType;
4787 eCsrAuthType RSNAuthType;
4788
4789 ENTER();
4790
4791 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304792
Jeff Johnson295189b2012-06-20 16:38:30 -07004793 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4794 {
4795 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4796 return -EINVAL;
4797 }
4798
4799 pRoamProfile = &pWextState->roamProfile;
4800
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304801 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004802 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004803 int ret = 0;
4804 hdd_station_ctx_t *pHddStaCtx;
4805 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4806 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4807
4808 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4809 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4810 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 {
4812 /* Issue disconnect to CSR */
4813 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304814 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4816 pAdapter->sessionId,
4817 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4818 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004819 ret = wait_for_completion_interruptible_timeout(
4820 &pAdapter->disconnect_comp_var,
4821 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4822 if (0 == ret)
4823 {
4824 VOS_ASSERT(0);
4825 }
4826 }
4827 }
4828 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4829 {
4830 ret = wait_for_completion_interruptible_timeout(
4831 &pAdapter->disconnect_comp_var,
4832 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4833 if (0 == ret)
4834 {
4835 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004836 }
4837 }
4838
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304839 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4841 {
4842 /*QoS not enabled in cfg file*/
4843 pRoamProfile->uapsd_mask = 0;
4844 }
4845 else
4846 {
4847 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304848 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004849 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4850 }
4851
4852 pRoamProfile->SSIDs.numOfSSIDs = 1;
4853 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4854 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304855 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4857 ssid, ssid_len);
4858
4859 if (bssid)
4860 {
4861 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4862 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4863 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304864 /* Save BSSID in seperate variable as well, as RoamProfile
4865 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 case of join failure we should send valid BSSID to supplicant
4867 */
4868 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4869 WNI_CFG_BSSID_LEN);
4870 }
4871
4872 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4873 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304874 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004875 /*set gen ie*/
4876 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4877 /*set auth*/
4878 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4879 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004880#ifdef FEATURE_WLAN_WAPI
4881 if (pAdapter->wapi_info.nWapiMode)
4882 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004883 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004884 switch (pAdapter->wapi_info.wapiAuthMode)
4885 {
4886 case WAPI_AUTH_MODE_PSK:
4887 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004888 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 pAdapter->wapi_info.wapiAuthMode);
4890 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4891 break;
4892 }
4893 case WAPI_AUTH_MODE_CERT:
4894 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004895 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 pAdapter->wapi_info.wapiAuthMode);
4897 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4898 break;
4899 }
4900 } // End of switch
4901 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4902 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4903 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004904 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004905 pRoamProfile->AuthType.numEntries = 1;
4906 pRoamProfile->EncryptionType.numEntries = 1;
4907 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4908 pRoamProfile->mcEncryptionType.numEntries = 1;
4909 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4910 }
4911 }
4912#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304913#ifdef WLAN_FEATURE_GTK_OFFLOAD
4914 /* Initializing gtkOffloadRequestParams */
4915 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4916 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4917 {
4918 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4919 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4920 0, sizeof (tSirGtkOffloadParams));
4921 }
4922#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 pRoamProfile->csrPersona = pAdapter->device_mode;
4924
Jeff Johnson32d95a32012-09-10 13:15:23 -07004925 if( operatingChannel )
4926 {
4927 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4928 pRoamProfile->ChannelInfo.numOfChannels = 1;
4929 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004930 else
4931 {
4932 pRoamProfile->ChannelInfo.ChannelList = NULL;
4933 pRoamProfile->ChannelInfo.numOfChannels = 0;
4934 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004935 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4936 {
4937 hdd_select_cbmode(pAdapter,operatingChannel);
4938 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004939 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4940 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304941 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004942 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004943 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4944 */
4945 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4946 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4947 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304948
4949 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004950 pAdapter->sessionId, pRoamProfile, &roamId);
4951
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004952 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304953 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4954
4955 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4957 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4958 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304959 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004960 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304961 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004962
4963 pRoamProfile->ChannelInfo.ChannelList = NULL;
4964 pRoamProfile->ChannelInfo.numOfChannels = 0;
4965
Jeff Johnson295189b2012-06-20 16:38:30 -07004966 }
4967 else
4968 {
4969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4970 return -EINVAL;
4971 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004972 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 return status;
4974}
4975
4976/*
4977 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4978 * This function is used to set the authentication type (OPEN/SHARED).
4979 *
4980 */
4981static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4982 enum nl80211_auth_type auth_type)
4983{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304984 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4986
4987 ENTER();
4988
4989 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304990 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304993 hddLog(VOS_TRACE_LEVEL_INFO,
4994 "%s: set authentication type to AUTOSWITCH", __func__);
4995 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4996 break;
4997
4998 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004999#ifdef WLAN_FEATURE_VOWIFI_11R
5000 case NL80211_AUTHTYPE_FT:
5001#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305002 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005003 "%s: set authentication type to OPEN", __func__);
5004 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5005 break;
5006
5007 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305008 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 "%s: set authentication type to SHARED", __func__);
5010 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5011 break;
5012#ifdef FEATURE_WLAN_CCX
5013 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 "%s: set authentication type to CCKM WPA", __func__);
5016 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5017 break;
5018#endif
5019
5020
5021 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305022 hddLog(VOS_TRACE_LEVEL_ERROR,
5023 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005024 auth_type);
5025 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5026 return -EINVAL;
5027 }
5028
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305029 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 pHddStaCtx->conn_info.authType;
5031 return 0;
5032}
5033
5034/*
5035 * FUNCTION: wlan_hdd_set_akm_suite
5036 * This function is used to set the key mgmt type(PSK/8021x).
5037 *
5038 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305039static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 u32 key_mgmt
5041 )
5042{
5043 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5044 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305045
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 /*set key mgmt type*/
5047 switch(key_mgmt)
5048 {
5049 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305050#ifdef WLAN_FEATURE_VOWIFI_11R
5051 case WLAN_AKM_SUITE_FT_PSK:
5052#endif
5053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 __func__);
5055 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5056 break;
5057
5058 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305059#ifdef WLAN_FEATURE_VOWIFI_11R
5060 case WLAN_AKM_SUITE_FT_8021X:
5061#endif
5062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 __func__);
5064 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5065 break;
5066#ifdef FEATURE_WLAN_CCX
5067#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5068#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5069 case WLAN_AKM_SUITE_CCKM:
5070 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5071 __func__);
5072 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5073 break;
5074#endif
5075
5076 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 __func__, key_mgmt);
5079 return -EINVAL;
5080
5081 }
5082 return 0;
5083}
5084
5085/*
5086 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 * (NONE/WEP40/WEP104/TKIP/CCMP).
5089 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305090static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5091 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 bool ucast
5093 )
5094{
5095 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5098
5099 ENTER();
5100
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305101 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 __func__, cipher);
5105 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5106 }
5107 else
5108 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305111 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 {
5113 case IW_AUTH_CIPHER_NONE:
5114 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5115 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305116
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305118 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305120
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305122 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005123 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305124
Jeff Johnson295189b2012-06-20 16:38:30 -07005125 case WLAN_CIPHER_SUITE_TKIP:
5126 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5127 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305128
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 case WLAN_CIPHER_SUITE_CCMP:
5130 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5131 break;
5132#ifdef FEATURE_WLAN_WAPI
5133 case WLAN_CIPHER_SUITE_SMS4:
5134 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5135 break;
5136#endif
5137
5138#ifdef FEATURE_WLAN_CCX
5139 case WLAN_CIPHER_SUITE_KRK:
5140 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5141 break;
5142#endif
5143 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 __func__, cipher);
5146 return -EOPNOTSUPP;
5147 }
5148 }
5149
5150 if (ucast)
5151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 __func__, encryptionType);
5154 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5155 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305156 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 encryptionType;
5158 }
5159 else
5160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305161 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005162 __func__, encryptionType);
5163 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5164 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5165 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5166 }
5167
5168 return 0;
5169}
5170
5171
5172/*
5173 * FUNCTION: wlan_hdd_cfg80211_set_ie
5174 * This function is used to parse WPA/RSN IE's.
5175 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305176int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5177 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 size_t ie_len
5179 )
5180{
5181 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5182 u8 *genie = ie;
5183 v_U16_t remLen = ie_len;
5184#ifdef FEATURE_WLAN_WAPI
5185 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5186 u16 *tmp;
5187 v_U16_t akmsuiteCount;
5188 int *akmlist;
5189#endif
5190 ENTER();
5191
5192 /* clear previous assocAddIE */
5193 pWextState->assocAddIE.length = 0;
5194 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5195
5196 while (remLen >= 2)
5197 {
5198 v_U16_t eLen = 0;
5199 v_U8_t elementId;
5200 elementId = *genie++;
5201 eLen = *genie++;
5202 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305203
5204 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305206
5207 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305209 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005210 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 -07005211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305212 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 "%s: Invalid WPA IE", __func__);
5214 return -EINVAL;
5215 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305216 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 {
5218 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305219 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005220 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305221
Jeff Johnson295189b2012-06-20 16:38:30 -07005222 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5223 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005224 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5225 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005226 VOS_ASSERT(0);
5227 return -ENOMEM;
5228 }
5229 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5230 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5231 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305232
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5234 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5235 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305237 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5238 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5240 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5241 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5242 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5243 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305245 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5246 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 /*Consider P2P IE, only for P2P Client */
5248 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5249 {
5250 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305251 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005252 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305253
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5255 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005256 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5257 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 VOS_ASSERT(0);
5259 return -ENOMEM;
5260 }
5261 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5262 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5263 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305264
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5266 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005268#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5270 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 /*Consider WFD IE, only for P2P Client */
5272 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5273 {
5274 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305275 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005276 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305277
Jeff Johnson295189b2012-06-20 16:38:30 -07005278 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5279 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005280 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5281 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005282 VOS_ASSERT(0);
5283 return -ENOMEM;
5284 }
5285 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5286 // WPS IE + P2P IE + WFD IE
5287 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5288 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5291 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5292 }
5293#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005294 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305295 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005296 HS20_OUI_TYPE_SIZE)) )
5297 {
5298 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305299 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005300 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005301
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005302 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5303 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005304 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5305 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005306 VOS_ASSERT(0);
5307 return -ENOMEM;
5308 }
5309 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5310 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005311
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005312 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5313 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5314 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005315
Jeff Johnson295189b2012-06-20 16:38:30 -07005316 break;
5317 case DOT11F_EID_RSN:
5318 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5319 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5320 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5321 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5322 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5323 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005324 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5325 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305326 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005327 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305328 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005329 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305330
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005331 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5332 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005333 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5334 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005335 VOS_ASSERT(0);
5336 return -ENOMEM;
5337 }
5338 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5339 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305340
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005341 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5342 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5343 break;
5344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005345#ifdef FEATURE_WLAN_WAPI
5346 case WLAN_EID_WAPI:
5347 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5348 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5349 pAdapter->wapi_info.nWapiMode);
5350 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305351 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 akmsuiteCount = WPA_GET_LE16(tmp);
5353 tmp = tmp + 1;
5354 akmlist = (int *)(tmp);
5355 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5356 {
5357 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5358 }
5359 else
5360 {
5361 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5362 VOS_ASSERT(0);
5363 return -EINVAL;
5364 }
5365
5366 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5367 {
5368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005369 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005370 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305373 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005375 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5377 }
5378 break;
5379#endif
5380 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305381 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005383 /* when Unknown IE is received we should break and continue
5384 * to the next IE in the buffer instead we were returning
5385 * so changing this to break */
5386 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 }
5388 genie += eLen;
5389 remLen -= eLen;
5390 }
5391 EXIT();
5392 return 0;
5393}
5394
5395/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305396 * FUNCTION: hdd_isWPAIEPresent
5397 * Parse the received IE to find the WPA IE
5398 *
5399 */
5400static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5401{
5402 v_U8_t eLen = 0;
5403 v_U16_t remLen = ie_len;
5404 v_U8_t elementId = 0;
5405
5406 while (remLen >= 2)
5407 {
5408 elementId = *ie++;
5409 eLen = *ie++;
5410 remLen -= 2;
5411 if (eLen > remLen)
5412 {
5413 hddLog(VOS_TRACE_LEVEL_ERROR,
5414 "%s: IE length is wrong %d", __func__, eLen);
5415 return FALSE;
5416 }
5417 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5418 {
5419 /* OUI - 0x00 0X50 0XF2
5420 WPA Information Element - 0x01
5421 WPA version - 0x01*/
5422 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5423 return TRUE;
5424 }
5425 ie += eLen;
5426 remLen -= eLen;
5427 }
5428 return FALSE;
5429}
5430
5431/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305433 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 * parameters during connect operation.
5435 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305436int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 struct cfg80211_connect_params *req
5438 )
5439{
5440 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305441 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 ENTER();
5443
5444 /*set wpa version*/
5445 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305447 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 {
5449 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305450 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305451 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 * since p2p ie is also put in same buffer.
5455 * */
5456 {
5457 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5458 }
5459 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5460 {
5461 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5462 }
5463 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305464
5465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 pWextState->wpaVersion);
5467
5468 /*set authentication type*/
5469 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5470
5471 if (0 > status)
5472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305473 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 "%s: failed to set authentication type ", __func__);
5475 return status;
5476 }
5477
5478 /*set key mgmt type*/
5479 if (req->crypto.n_akm_suites)
5480 {
5481 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5482 if (0 > status)
5483 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 __func__);
5486 return status;
5487 }
5488 }
5489
5490 /*set pairwise cipher type*/
5491 if (req->crypto.n_ciphers_pairwise)
5492 {
5493 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5494 req->crypto.ciphers_pairwise[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 else
5503 {
5504 /*Reset previous cipher suite to none*/
5505 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5506 if (0 > status)
5507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305508 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 "%s: failed to set unicast cipher type", __func__);
5510 return status;
5511 }
5512 }
5513
5514 /*set group cipher type*/
5515 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5516 false);
5517
5518 if (0 > status)
5519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 __func__);
5522 return status;
5523 }
5524
Chet Lanctot186b5732013-03-18 10:26:30 -07005525#ifdef WLAN_FEATURE_11W
5526 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5527#endif
5528
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5530 if (req->ie_len)
5531 {
5532 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5533 if ( 0 > status)
5534 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305535 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 __func__);
5537 return status;
5538 }
5539 }
5540
5541 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305542 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 {
5544 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5545 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5546 )
5547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 __func__);
5553 return -EOPNOTSUPP;
5554 }
5555 else
5556 {
5557 u8 key_len = req->key_len;
5558 u8 key_idx = req->key_idx;
5559
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305560 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 && (CSR_MAX_NUM_KEY > key_idx)
5562 )
5563 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305564 hddLog(VOS_TRACE_LEVEL_INFO,
5565 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 __func__, key_idx, key_len);
5567 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305570 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 (u8)key_len;
5572 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5573 }
5574 }
5575 }
5576 }
5577
5578 return status;
5579}
5580
5581/*
5582 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 * parameters during connect operation.
5585 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305586static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 struct net_device *ndev,
5588 struct cfg80211_connect_params *req
5589 )
5590{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305591 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5594 hdd_context_t *pHddCtx = NULL;
5595
5596 ENTER();
5597
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305598 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305601 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5602 status = wlan_hdd_validate_context(pHddCtx);
5603
5604 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5607 "%s: HDD context is not valid", __func__);
5608 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 }
5610
5611#ifdef WLAN_BTAMP_FEATURE
5612 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305613 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305615 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005617 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 }
5619#endif
5620 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305621 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005622
5623 if ( 0 > status)
5624 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 __func__);
5627 return status;
5628 }
5629
5630 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005631 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5633 (vos_concurrent_sessions_running()))
5634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305635 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 }
5637
Mohit Khanna765234a2012-09-11 15:08:35 -07005638 if ( req->channel )
5639 {
5640 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5641 req->ssid_len, req->bssid,
5642 req->channel->hw_value);
5643 }
5644 else
5645 {
5646 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305647 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005649
5650 if (0 > status)
5651 {
5652 //ReEnable BMPS if disabled
5653 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5654 (NULL != pHddCtx))
5655 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305656 if (pHddCtx->hdd_wlan_suspended)
5657 {
5658 hdd_set_pwrparams(pHddCtx);
5659 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 //ReEnable Bmps and Imps back
5661 hdd_enable_bmps_imps(pHddCtx);
5662 }
5663
5664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5665 return status;
5666 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305667 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 EXIT();
5669 return status;
5670}
5671
5672
5673/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305674 * FUNCTION: wlan_hdd_disconnect
5675 * This function is used to issue a disconnect request to SME
5676 */
5677int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5678{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305679 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305680 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305681 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5682
5683 status = wlan_hdd_validate_context(pHddCtx);
5684
5685 if (0 != status)
5686 {
5687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5688 "%s: HDD context is not valid", __func__);
5689 return status;
5690 }
5691
5692 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305693 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305694 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305695
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305696 /*issue disconnect*/
5697 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5698 pAdapter->sessionId, reason);
5699
5700 if ( 0 != status )
5701 {
5702 hddLog(VOS_TRACE_LEVEL_ERROR,
5703 "%s csrRoamDisconnect failure, returned %d \n",
5704 __func__, (int)status );
5705 return -EINVAL;
5706 }
5707 wait_for_completion_interruptible_timeout(
5708 &pAdapter->disconnect_comp_var,
5709 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5710 /*stop tx queues*/
5711 netif_tx_disable(pAdapter->dev);
5712 netif_carrier_off(pAdapter->dev);
5713 return status;
5714}
5715
5716
5717/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 * FUNCTION: wlan_hdd_cfg80211_disconnect
5719 * This function is used to issue a disconnect request to SME
5720 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305721static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 struct net_device *dev,
5723 u16 reason
5724 )
5725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5727 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305729 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005731 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305732#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005733 tANI_U8 staIdx;
5734#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305735
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305737
5738 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005739 __func__,pAdapter->device_mode);
5740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5742 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005743
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305744 status = wlan_hdd_validate_context(pHddCtx);
5745
5746 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5749 "%s: HDD context is not valid", __func__);
5750 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305752
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 if (NULL != pRoamProfile)
5754 {
5755 /*issue disconnect request to SME, if station is in connected state*/
5756 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305758 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305760 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 switch(reason)
5762 {
5763 case WLAN_REASON_MIC_FAILURE:
5764 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5765 break;
5766
5767 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5768 case WLAN_REASON_DISASSOC_AP_BUSY:
5769 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5770 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5771 break;
5772
5773 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5774 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5775 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5776 break;
5777
5778 case WLAN_REASON_DEAUTH_LEAVING:
5779 default:
5780 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5781 break;
5782 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305783 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5784 pScanInfo = &pHddCtx->scan_info;
5785 if (pScanInfo->mScanPending)
5786 {
5787 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5788 "Aborting Scan");
5789 hdd_abort_mac_scan(pHddCtx);
5790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005791
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005792#ifdef FEATURE_WLAN_TDLS
5793 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005794 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005795 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005796 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5797 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005798 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005799 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005800 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005801 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005802 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005803 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005804 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005805 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005806 pAdapter->sessionId,
5807 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005808 }
5809 }
5810#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305811 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5812 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 {
5814 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305815 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 __func__, (int)status );
5817 return -EINVAL;
5818 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 }
5820 }
5821 else
5822 {
5823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5824 }
5825
5826 return status;
5827}
5828
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305829
Jeff Johnson295189b2012-06-20 16:38:30 -07005830/*
5831 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305832 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 * settings in IBSS mode.
5834 */
5835static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305836 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 struct cfg80211_ibss_params *params
5838 )
5839{
5840 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305841 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5843 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305844
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 ENTER();
5846
5847 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5848
5849 if (params->ie_len && ( NULL != params->ie) )
5850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305851 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 {
5853 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5854 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5855 }
5856 else
5857 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005858 tDot11fIEWPA dot11WPAIE;
5859 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5860
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005862 // Unpack the WPA IE
5863 //Skip past the EID byte and length byte - and four byte WiFi OUI
5864 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5865 &params->ie[2+4],
5866 params->ie[1] - 4,
5867 &dot11WPAIE);
5868 /*Extract the multicast cipher, the encType for unicast
5869 cipher for wpa-none is none*/
5870 encryptionType =
5871 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 }
5873 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5874
5875 if (0 > status)
5876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 __func__);
5879 return status;
5880 }
5881 }
5882
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305883 pWextState->roamProfile.AuthType.authType[0] =
5884 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5886
5887 if (params->privacy)
5888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 /* Security enabled IBSS, At this time there is no information available
5890 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 *enable privacy bit in beacons */
5896
5897 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5898 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005899 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5900 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5902 pWextState->roamProfile.EncryptionType.numEntries = 1;
5903 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 return status;
5905}
5906
5907/*
5908 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 struct net_device *dev,
5913 struct cfg80211_ibss_params *params
5914 )
5915{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5918 tCsrRoamProfile *pRoamProfile;
5919 int status;
5920 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305921 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005922
5923 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924
5925 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5927
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305928 status = wlan_hdd_validate_context(pHddCtx);
5929
5930 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5933 "%s: HDD context is not valid", __func__);
5934 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 }
5936
5937 if (NULL == pWextState)
5938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 __func__);
5941 return -EIO;
5942 }
5943
5944 pRoamProfile = &pWextState->roamProfile;
5945
5946 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305948 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 "%s Interface type is not set to IBSS \n", __func__);
5950 return -EINVAL;
5951 }
5952
5953 /* Set Channel */
5954 if (NULL != params->channel)
5955 {
5956 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005957 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5958 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5959 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5960 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305963 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005964 ieee80211_frequency_to_channel(params->channel->center_freq);
5965
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005966
5967 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5968 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005970 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5971 __func__);
5972 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005974
5975 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005977 if (channelNum == validChan[indx])
5978 {
5979 break;
5980 }
5981 }
5982 if (indx >= numChans)
5983 {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 __func__, channelNum);
5986 return -EINVAL;
5987 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005988 /* Set the Operational Channel */
5989 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5990 channelNum);
5991 pRoamProfile->ChannelInfo.numOfChannels = 1;
5992 pHddStaCtx->conn_info.operationChannel = channelNum;
5993 pRoamProfile->ChannelInfo.ChannelList =
5994 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 }
5996
5997 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305998 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 if (status < 0)
6000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 __func__);
6003 return status;
6004 }
6005
6006 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006008 params->ssid_len, params->bssid,
6009 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006010
6011 if (0 > status)
6012 {
6013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6014 return status;
6015 }
6016
6017 return 0;
6018}
6019
6020/*
6021 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306022 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306024static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 struct net_device *dev
6026 )
6027{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6030 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306031 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6032 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006033
6034 ENTER();
6035
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306036 status = wlan_hdd_validate_context(pHddCtx);
6037
6038 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6041 "%s: HDD context is not valid", __func__);
6042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006043 }
6044
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6046 if (NULL == pWextState)
6047 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306048 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006049 __func__);
6050 return -EIO;
6051 }
6052
6053 pRoamProfile = &pWextState->roamProfile;
6054
6055 /* Issue disconnect only if interface type is set to IBSS */
6056 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6057 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306058 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 __func__);
6060 return -EINVAL;
6061 }
6062
6063 /* Issue Disconnect request */
6064 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6065 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6066 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6067
6068 return 0;
6069}
6070
6071/*
6072 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6073 * This function is used to set the phy parameters
6074 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6075 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306076static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 u32 changed)
6078{
6079 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6080 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306081 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006082
6083 ENTER();
6084
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306085 status = wlan_hdd_validate_context(pHddCtx);
6086
6087 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006088 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6090 "%s: HDD context is not valid", __func__);
6091 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006092 }
6093
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6095 {
6096 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6097 WNI_CFG_RTS_THRESHOLD_STAMAX :
6098 wiphy->rts_threshold;
6099
6100 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 hddLog(VOS_TRACE_LEVEL_ERROR,
6104 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 __func__, rts_threshold);
6106 return -EINVAL;
6107 }
6108
6109 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6110 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306111 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306113 hddLog(VOS_TRACE_LEVEL_ERROR,
6114 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 __func__, rts_threshold);
6116 return -EIO;
6117 }
6118
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306119 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 rts_threshold);
6121 }
6122
6123 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6124 {
6125 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6126 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6127 wiphy->frag_threshold;
6128
6129 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306130 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306132 hddLog(VOS_TRACE_LEVEL_ERROR,
6133 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 frag_threshold);
6135 return -EINVAL;
6136 }
6137
6138 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6139 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306140 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142 hddLog(VOS_TRACE_LEVEL_ERROR,
6143 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 __func__, frag_threshold);
6145 return -EIO;
6146 }
6147
6148 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6149 frag_threshold);
6150 }
6151
6152 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6153 || (changed & WIPHY_PARAM_RETRY_LONG))
6154 {
6155 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6156 wiphy->retry_short :
6157 wiphy->retry_long;
6158
6159 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6160 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 __func__, retry_value);
6164 return -EINVAL;
6165 }
6166
6167 if (changed & WIPHY_PARAM_RETRY_SHORT)
6168 {
6169 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6170 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306173 hddLog(VOS_TRACE_LEVEL_ERROR,
6174 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006175 __func__, retry_value);
6176 return -EIO;
6177 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 __func__, retry_value);
6180 }
6181 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6182 {
6183 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6184 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306185 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306187 hddLog(VOS_TRACE_LEVEL_ERROR,
6188 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 __func__, retry_value);
6190 return -EIO;
6191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306192 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 __func__, retry_value);
6194 }
6195 }
6196
6197 return 0;
6198}
6199
6200/*
6201 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6202 * This function is used to set the txpower
6203 */
6204static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6205#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306206 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006207#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306208 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006209#endif
6210 int dbm)
6211{
6212 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306213 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6215 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306216 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006217
6218 ENTER();
6219
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306220 status = wlan_hdd_validate_context(pHddCtx);
6221
6222 if (0 != status)
6223 {
6224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6225 "%s: HDD context is not valid", __func__);
6226 return status;
6227 }
6228
6229 hHal = pHddCtx->hHal;
6230
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306231 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6232 dbm, ccmCfgSetCallback,
6233 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6237 return -EIO;
6238 }
6239
6240 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6241 dbm);
6242
6243 switch(type)
6244 {
6245 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6246 /* Fall through */
6247 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6248 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6249 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6251 __func__);
6252 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 }
6254 break;
6255 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 __func__);
6258 return -EOPNOTSUPP;
6259 break;
6260 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6262 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 return -EIO;
6264 }
6265
6266 return 0;
6267}
6268
6269/*
6270 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6271 * This function is used to read the txpower
6272 */
6273static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6274{
6275
6276 hdd_adapter_t *pAdapter;
6277 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306278 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006279
Jeff Johnsone7245742012-09-05 17:12:55 -07006280 ENTER();
6281
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306282 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006283
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306284 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006285 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6287 "%s: HDD context is not valid", __func__);
6288 *dbm = 0;
6289 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006290 }
6291
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6293 if (NULL == pAdapter)
6294 {
6295 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6296 return -ENOENT;
6297 }
6298
6299 wlan_hdd_get_classAstats(pAdapter);
6300 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6301
Jeff Johnsone7245742012-09-05 17:12:55 -07006302 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 return 0;
6304}
6305
6306static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6307 u8* mac, struct station_info *sinfo)
6308{
6309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6310 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6311 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6312 tANI_U8 rate_flags;
6313
6314 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6315 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006316
6317 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6318 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6319 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6320 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6321 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6322 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6323 tANI_U16 maxRate = 0;
6324 tANI_U16 myRate;
6325 tANI_U16 currentRate = 0;
6326 tANI_U8 maxSpeedMCS = 0;
6327 tANI_U8 maxMCSIdx = 0;
6328 tANI_U8 rateFlag = 1;
6329 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006330 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306331 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332
Leo Chang6f8870f2013-03-26 18:11:36 -07006333#ifdef WLAN_FEATURE_11AC
6334 tANI_U32 vht_mcs_map;
6335 eDataRate11ACMaxMcs vhtMaxMcs;
6336#endif /* WLAN_FEATURE_11AC */
6337
Jeff Johnsone7245742012-09-05 17:12:55 -07006338 ENTER();
6339
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6341 (0 == ssidlen))
6342 {
6343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6344 " Invalid ssidlen, %d", __func__, ssidlen);
6345 /*To keep GUI happy*/
6346 return 0;
6347 }
6348
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306349 status = wlan_hdd_validate_context(pHddCtx);
6350
6351 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6354 "%s: HDD context is not valid", __func__);
6355 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006356 }
6357
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6359 sinfo->filled |= STATION_INFO_SIGNAL;
6360
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006361 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6363
6364 //convert to the UI units of 100kbps
6365 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6366
6367#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006368 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 -07006369 sinfo->signal,
6370 pCfg->reportMaxLinkSpeed,
6371 myRate,
6372 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006373 (int) pCfg->linkSpeedRssiMid,
6374 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006375 (int) rate_flags,
6376 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006377#endif //LINKSPEED_DEBUG_ENABLED
6378
6379 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6380 {
6381 // we do not want to necessarily report the current speed
6382 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6383 {
6384 // report the max possible speed
6385 rssidx = 0;
6386 }
6387 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6388 {
6389 // report the max possible speed with RSSI scaling
6390 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6391 {
6392 // report the max possible speed
6393 rssidx = 0;
6394 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006395 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 {
6397 // report middle speed
6398 rssidx = 1;
6399 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006400 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6401 {
6402 // report middle speed
6403 rssidx = 2;
6404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 else
6406 {
6407 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006408 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 }
6410 }
6411 else
6412 {
6413 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6414 hddLog(VOS_TRACE_LEVEL_ERROR,
6415 "%s: Invalid value for reportMaxLinkSpeed: %u",
6416 __func__, pCfg->reportMaxLinkSpeed);
6417 rssidx = 0;
6418 }
6419
6420 maxRate = 0;
6421
6422 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306423 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6424 OperationalRates, &ORLeng))
6425 {
6426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6427 /*To keep GUI happy*/
6428 return 0;
6429 }
6430
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 for (i = 0; i < ORLeng; i++)
6432 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006433 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 {
6435 /* Validate Rate Set */
6436 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6437 {
6438 currentRate = supported_data_rate[j].supported_rate[rssidx];
6439 break;
6440 }
6441 }
6442 /* Update MAX rate */
6443 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6444 }
6445
6446 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306447 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6448 ExtendedRates, &ERLeng))
6449 {
6450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6451 /*To keep GUI happy*/
6452 return 0;
6453 }
6454
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 for (i = 0; i < ERLeng; i++)
6456 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006457 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 {
6459 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6460 {
6461 currentRate = supported_data_rate[j].supported_rate[rssidx];
6462 break;
6463 }
6464 }
6465 /* Update MAX rate */
6466 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 /* Get MCS Rate Set -- but only if we are connected at MCS
6469 rates or if we are always reporting max speed or if we have
6470 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006471 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306473 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6474 MCSRates, &MCSLeng))
6475 {
6476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6477 /*To keep GUI happy*/
6478 return 0;
6479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006481#ifdef WLAN_FEATURE_11AC
6482 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306483 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006485 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306486 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006487 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006489 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006491 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006493 maxMCSIdx = 7;
6494 }
6495 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6496 {
6497 maxMCSIdx = 8;
6498 }
6499 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6500 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306501 //VHT20 is supporting 0~8
6502 if (rate_flags & eHAL_TX_RATE_VHT20)
6503 maxMCSIdx = 8;
6504 else
6505 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006506 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306507
6508 if (rate_flags & eHAL_TX_RATE_VHT80)
6509 {
6510 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6511 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6512 }
6513 else if (rate_flags & eHAL_TX_RATE_VHT40)
6514 {
6515 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6516 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6517 }
6518 else if (rate_flags & eHAL_TX_RATE_VHT20)
6519 {
6520 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6521 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6522 }
6523
Leo Chang6f8870f2013-03-26 18:11:36 -07006524 maxSpeedMCS = 1;
6525 if (currentRate > maxRate)
6526 {
6527 maxRate = currentRate;
6528 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306529
Leo Chang6f8870f2013-03-26 18:11:36 -07006530 }
6531 else
6532#endif /* WLAN_FEATURE_11AC */
6533 {
6534 if (rate_flags & eHAL_TX_RATE_HT40)
6535 {
6536 rateFlag |= 1;
6537 }
6538 if (rate_flags & eHAL_TX_RATE_SGI)
6539 {
6540 rateFlag |= 2;
6541 }
6542
6543 for (i = 0; i < MCSLeng; i++)
6544 {
6545 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6546 for (j = 0; j < temp; j++)
6547 {
6548 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6549 {
6550 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6551 break;
6552 }
6553 }
6554 if ((j < temp) && (currentRate > maxRate))
6555 {
6556 maxRate = currentRate;
6557 maxSpeedMCS = 1;
6558 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6559 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 }
6561 }
6562 }
6563
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306564 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6565 {
6566 maxRate = myRate;
6567 maxSpeedMCS = 1;
6568 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6569 }
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006572 if (((maxRate < myRate) && (0 == rssidx)) ||
6573 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 {
6575 maxRate = myRate;
6576 if (rate_flags & eHAL_TX_RATE_LEGACY)
6577 {
6578 maxSpeedMCS = 0;
6579 }
6580 else
6581 {
6582 maxSpeedMCS = 1;
6583 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6584 }
6585 }
6586
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306587 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 {
6589 sinfo->txrate.legacy = maxRate;
6590#ifdef LINKSPEED_DEBUG_ENABLED
6591 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6592#endif //LINKSPEED_DEBUG_ENABLED
6593 }
6594 else
6595 {
6596 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006597#ifdef WLAN_FEATURE_11AC
6598 sinfo->txrate.nss = 1;
6599 if (rate_flags & eHAL_TX_RATE_VHT80)
6600 {
6601 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306602 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006603 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306604 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006605 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306606 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6607 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6608 }
6609 else if (rate_flags & eHAL_TX_RATE_VHT20)
6610 {
6611 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6612 }
6613#endif /* WLAN_FEATURE_11AC */
6614 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6615 {
6616 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6617 if (rate_flags & eHAL_TX_RATE_HT40)
6618 {
6619 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6620 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 if (rate_flags & eHAL_TX_RATE_SGI)
6623 {
6624 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6625 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306626
Jeff Johnson295189b2012-06-20 16:38:30 -07006627#ifdef LINKSPEED_DEBUG_ENABLED
6628 pr_info("Reporting MCS rate %d flags %x\n",
6629 sinfo->txrate.mcs,
6630 sinfo->txrate.flags );
6631#endif //LINKSPEED_DEBUG_ENABLED
6632 }
6633 }
6634 else
6635 {
6636 // report current rate instead of max rate
6637
6638 if (rate_flags & eHAL_TX_RATE_LEGACY)
6639 {
6640 //provide to the UI in units of 100kbps
6641 sinfo->txrate.legacy = myRate;
6642#ifdef LINKSPEED_DEBUG_ENABLED
6643 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6644#endif //LINKSPEED_DEBUG_ENABLED
6645 }
6646 else
6647 {
6648 //must be MCS
6649 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006650#ifdef WLAN_FEATURE_11AC
6651 sinfo->txrate.nss = 1;
6652 if (rate_flags & eHAL_TX_RATE_VHT80)
6653 {
6654 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6655 }
6656 else
6657#endif /* WLAN_FEATURE_11AC */
6658 {
6659 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6660 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 if (rate_flags & eHAL_TX_RATE_SGI)
6662 {
6663 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6664 }
6665 if (rate_flags & eHAL_TX_RATE_HT40)
6666 {
6667 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6668 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006669#ifdef WLAN_FEATURE_11AC
6670 else if (rate_flags & eHAL_TX_RATE_VHT80)
6671 {
6672 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6673 }
6674#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006675#ifdef LINKSPEED_DEBUG_ENABLED
6676 pr_info("Reporting actual MCS rate %d flags %x\n",
6677 sinfo->txrate.mcs,
6678 sinfo->txrate.flags );
6679#endif //LINKSPEED_DEBUG_ENABLED
6680 }
6681 }
6682 sinfo->filled |= STATION_INFO_TX_BITRATE;
6683
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006684 sinfo->tx_packets =
6685 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6686 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6687 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6688 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6689
6690 sinfo->tx_retries =
6691 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6692 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6693 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6694 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6695
6696 sinfo->tx_failed =
6697 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6698 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6699 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6700 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6701
6702 sinfo->filled |=
6703 STATION_INFO_TX_PACKETS |
6704 STATION_INFO_TX_RETRIES |
6705 STATION_INFO_TX_FAILED;
6706
6707 EXIT();
6708 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006709}
6710
6711static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07006712 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07006713{
6714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306715 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306717 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006718
Jeff Johnsone7245742012-09-05 17:12:55 -07006719 ENTER();
6720
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 if (NULL == pAdapter)
6722 {
6723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6724 return -ENODEV;
6725 }
6726
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306728 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306730 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306731 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6733 "%s: HDD context is not valid", __func__);
6734 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306735 }
6736
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306737 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6738 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6739 (pHddCtx->cfg_ini->fhostArpOffload) &&
6740 (eConnectionState_Associated ==
6741 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6742 {
6743 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6744 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6745 {
6746 hddLog(VOS_TRACE_LEVEL_INFO,
6747 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6748 __func__, vos_status);
6749 }
6750 }
6751
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 /**The get power cmd from the supplicant gets updated by the nl only
6753 *on successful execution of the function call
6754 *we are oppositely mapped w.r.t mode in the driver
6755 **/
6756 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6757
Jeff Johnsone7245742012-09-05 17:12:55 -07006758 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 if (VOS_STATUS_E_FAILURE == vos_status)
6760 {
6761 return -EINVAL;
6762 }
6763 return 0;
6764}
6765
6766
6767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6768static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6769 struct net_device *netdev,
6770 u8 key_index)
6771{
Jeff Johnsone7245742012-09-05 17:12:55 -07006772 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 return 0;
6774}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306775#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
6777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6778static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6779 struct net_device *dev,
6780 struct ieee80211_txq_params *params)
6781{
Jeff Johnsone7245742012-09-05 17:12:55 -07006782 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 return 0;
6784}
6785#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6786static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6787 struct ieee80211_txq_params *params)
6788{
Jeff Johnsone7245742012-09-05 17:12:55 -07006789 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 return 0;
6791}
6792#endif //LINUX_VERSION_CODE
6793
6794static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6795 struct net_device *dev, u8 *mac)
6796{
6797 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306798 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006799 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306800 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006801 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006802
Jeff Johnsone7245742012-09-05 17:12:55 -07006803 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306804 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 return -EINVAL;
6808 }
6809
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6811 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306813 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6816 "%s: HDD context is not valid", __func__);
6817 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006818 }
6819
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 )
6823 {
6824 if( NULL == mac )
6825 {
6826 v_U16_t i;
6827 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6828 {
6829 if(pAdapter->aStaInfo[i].isUsed)
6830 {
6831 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6832 hddLog(VOS_TRACE_LEVEL_INFO,
6833 "%s: Delete STA with MAC::"
6834 "%02x:%02x:%02x:%02x:%02x:%02x",
6835 __func__,
6836 macAddr[0], macAddr[1], macAddr[2],
6837 macAddr[3], macAddr[4], macAddr[5]);
6838 hdd_softap_sta_deauth(pAdapter, macAddr);
6839 }
6840 }
6841 }
6842 else
6843 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006844
6845 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6846 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6847 {
6848 hddLog(VOS_TRACE_LEVEL_INFO,
6849 "%s: Skip this DEL STA as this is not used::"
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 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6858 {
6859 hddLog(VOS_TRACE_LEVEL_INFO,
6860 "%s: Skip this DEL STA as deauth is in progress::"
6861 "%02x:%02x:%02x:%02x:%02x:%02x",
6862 __func__,
6863 mac[0], mac[1], mac[2],
6864 mac[3], mac[4], mac[5]);
6865 return -ENOENT;
6866 }
6867
6868 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 hddLog(VOS_TRACE_LEVEL_INFO,
6871 "%s: Delete STA with MAC::"
6872 "%02x:%02x:%02x:%02x:%02x:%02x",
6873 __func__,
6874 mac[0], mac[1], mac[2],
6875 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006876
6877 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6878 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6879 {
6880 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6881 hddLog(VOS_TRACE_LEVEL_INFO,
6882 "%s: STA removal failed for ::"
6883 "%02x:%02x:%02x:%02x:%02x:%02x",
6884 __func__,
6885 mac[0], mac[1], mac[2],
6886 mac[3], mac[4], mac[5]);
6887 return -ENOENT;
6888 }
6889
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 }
6891 }
6892
6893 EXIT();
6894
6895 return 0;
6896}
6897
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006898static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6899 struct net_device *dev, u8 *mac, struct station_parameters *params)
6900{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006901 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006902#ifdef FEATURE_WLAN_TDLS
6903 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006904 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006905 mask = params->sta_flags_mask;
6906
6907 set = params->sta_flags_set;
6908
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006909#ifdef WLAN_FEATURE_TDLS_DEBUG
6910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6911 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6912 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6913#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006914
6915 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6916 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006917 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006918 }
6919 }
6920#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006921 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006922}
6923
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006924
6925#ifdef FEATURE_WLAN_LFR
6926static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006927 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006928{
6929#define MAX_PMKSAIDS_IN_CACHE 8
6930 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 static tANI_U32 i; // HDD Local Cache index
6932 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6934 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306935 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306936 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306938 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306939
Jeff Johnsone7245742012-09-05 17:12:55 -07006940 ENTER();
6941
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306942 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306943 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946 return -EINVAL;
6947 }
6948
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6950 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006951
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306952 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006953 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6955 "%s: HDD context is not valid", __func__);
6956 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957 }
6958
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306959 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006960 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6961
6962 for (j = 0; j < i; j++)
6963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306964 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006965 pmksa->bssid, WNI_CFG_BSSID_LEN))
6966 {
6967 /* BSSID matched previous entry. Overwrite it. */
6968 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306969 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006970 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306971 vos_mem_copy(PMKIDCache[j].PMKID,
6972 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006973 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006975 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006976 dump_bssid(pmksa->bssid);
6977 dump_pmkid(halHandle, pmksa->pmkid);
6978 break;
6979 }
6980 }
6981
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006982 /* Check we compared all entries,if then take the first slot now */
6983 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6984
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006985 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 {
6987 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6988 vos_mem_copy(PMKIDCache[i].BSSID,
6989 pmksa->bssid, ETHER_ADDR_LEN);
6990 vos_mem_copy(PMKIDCache[i].PMKID,
6991 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306993 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006994 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006995 dump_bssid(pmksa->bssid);
6996 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306997 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006998 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007000 }
7001
7002
7003 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307004 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007005 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307006 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007007 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007008 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307009 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7010 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007011 i );
7012 return 0;
7013}
7014
7015
7016static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007017 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007018{
Jeff Johnsone7245742012-09-05 17:12:55 -07007019 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007020 // TODO: Implement this later.
7021 return 0;
7022}
7023
7024static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7025{
Jeff Johnsone7245742012-09-05 17:12:55 -07007026 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007027 // TODO: Implement this later.
7028 return 0;
7029}
7030#endif
7031
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007032#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307033static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007034 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7035{
7036 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7037 hdd_station_ctx_t *pHddStaCtx;
7038
7039 if (NULL == pAdapter)
7040 {
7041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7042 return -ENODEV;
7043 }
7044
7045 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7046
7047 // Added for debug on reception of Re-assoc Req.
7048 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307050 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007051 ftie->ie_len);
7052 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7053 }
7054
7055#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307056 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007057 ftie->ie_len);
7058#endif
7059
7060 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307061 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7062 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007063 ftie->ie_len);
7064 return 0;
7065}
7066#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007067
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307068#ifdef FEATURE_WLAN_SCAN_PNO
7069
7070void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7071 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7072{
7073 int ret;
7074 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7075 hdd_context_t *pHddCtx;
7076
7077 if (NULL == pAdapter)
7078 {
7079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7080 "%s: HDD adapter is Null", __func__);
7081 return ;
7082 }
7083
7084 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7085 if (NULL == pHddCtx)
7086 {
7087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7088 "%s: HDD context is Null!!!", __func__);
7089 return ;
7090 }
7091
7092 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7093
7094 if (0 > ret)
7095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7096
7097 cfg80211_sched_scan_results(pHddCtx->wiphy);
7098}
7099
7100/*
7101 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7102 * NL interface to enable PNO
7103 */
7104static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7105 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7106{
7107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7108 tpSirPNOScanReq pPnoRequest = NULL;
7109 hdd_context_t *pHddCtx;
7110 tHalHandle hHal;
7111 v_U32_t i, indx, num_ch;
7112 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7113 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7114 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7115 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307116 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307117
7118 if (NULL == pAdapter)
7119 {
7120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7121 "%s: HDD adapter is Null", __func__);
7122 return -ENODEV;
7123 }
7124
7125 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307126 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307127
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307128 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307129 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7131 "%s: HDD context is not valid", __func__);
7132 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307133 }
7134
7135 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7136 if (NULL == hHal)
7137 {
7138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7139 "%s: HAL context is Null!!!", __func__);
7140 return -EAGAIN;
7141 }
7142
7143 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7144 if (NULL == pPnoRequest)
7145 {
7146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7147 "%s: vos_mem_malloc failed", __func__);
7148 return -ENODEV;
7149 }
7150
7151 pPnoRequest->enable = 1; /*Enable PNO */
7152 pPnoRequest->ucNetworksCount = request->n_match_sets;
7153
7154 if (( !pPnoRequest->ucNetworksCount ) ||
7155 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7156 {
7157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7158 "Network input is not correct");
7159 goto error;
7160 }
7161
7162 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7163 {
7164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7165 "Incorrect number of channels");
7166 goto error;
7167 }
7168
7169 /* Framework provides one set of channels(all)
7170 * common for all saved profile */
7171 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7172 channels_allowed, &num_channels_allowed))
7173 {
7174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7175 "%s: failed to get valid channel list", __func__);
7176 goto error;
7177 }
7178 /* Checking each channel against allowed channel list */
7179 num_ch = 0;
7180 for (i = 0; i < request->n_channels; i++)
7181 {
7182 for (indx = 0; indx < num_channels_allowed; indx++)
7183 {
7184 if (request->channels[i]->hw_value == channels_allowed[indx])
7185 {
7186 valid_ch[num_ch++] = request->channels[i]->hw_value;
7187 break ;
7188 }
7189 }
7190 }
7191
7192 /* Filling per profile params */
7193 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7194 {
7195 pPnoRequest->aNetworks[i].ssId.length =
7196 request->match_sets[i].ssid.ssid_len;
7197
7198 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7199 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7200 {
7201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7202 "SSID Len %d is not correct for network %d",
7203 pPnoRequest->aNetworks[i].ssId.length, i);
7204 goto error;
7205 }
7206
7207 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7208 request->match_sets[i].ssid.ssid,
7209 request->match_sets[i].ssid.ssid_len);
7210 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7211 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7212 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7213
7214 /*Copying list of valid channel into request */
7215 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7216 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7217
7218 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7219 }
7220
7221 /* framework provides interval in ms */
7222 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7223 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7224 (request->interval)/1000;
7225 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7226 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7227
7228 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7229 pPnoRequest, pAdapter->sessionId,
7230 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7231 if (eHAL_STATUS_SUCCESS != status)
7232 {
7233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7234 "Failed to enable PNO");
7235 goto error;
7236 }
7237
7238error:
7239 vos_mem_free(pPnoRequest);
7240 return status;
7241}
7242
7243/*
7244 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7245 * NL interface to disable PNO
7246 */
7247static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7248 struct net_device *dev)
7249{
7250 eHalStatus status = eHAL_STATUS_FAILURE;
7251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7252 hdd_context_t *pHddCtx;
7253 tHalHandle hHal;
7254 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307255 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307256
7257 ENTER();
7258
7259 if (NULL == pAdapter)
7260 {
7261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7262 "%s: HDD adapter is Null", __func__);
7263 return -ENODEV;
7264 }
7265
7266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307267 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307268
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307269 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307270 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7272 "%s: HDD context is not valid", __func__);
7273 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307274 }
7275
7276 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7277 if (NULL == hHal)
7278 {
7279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7280 "%s: HAL context is Null!!!", __func__);
7281 return -EAGAIN;
7282 }
7283
7284 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7285 if (NULL == pPnoRequest)
7286 {
7287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7288 "%s: vos_mem_malloc failed", __func__);
7289 return -ENODEV;
7290 }
7291
7292 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7293 pPnoRequest->enable = 0; /* Disable PNO */
7294 pPnoRequest->ucNetworksCount = 0;
7295
7296 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7297 pAdapter->sessionId,
7298 NULL, pAdapter);
7299 if (eHAL_STATUS_SUCCESS != status)
7300 {
7301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7302 "Failed to disabled PNO");
7303 }
7304
7305 vos_mem_free(pPnoRequest);
7306
7307 EXIT();
7308 return status;
7309}
7310
7311#endif /*FEATURE_WLAN_SCAN_PNO*/
7312
7313
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007314#ifdef FEATURE_WLAN_TDLS
7315static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7316 u8 *peer, u8 action_code, u8 dialog_token,
7317 u16 status_code, const u8 *buf, size_t len)
7318{
7319
7320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7321 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007322 u8 peerMac[6];
7323 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007324 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007325 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007326 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007327
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007328 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007331 "Invalid arguments");
7332 return -EINVAL;
7333 }
7334
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007335 if (pHddCtx->isLogpInProgress)
7336 {
7337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7338 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007339 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007340 return -EBUSY;
7341 }
7342
Hoonki Lee27511902013-03-14 18:19:06 -07007343 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007344 {
Hoonki Lee27511902013-03-14 18:19:06 -07007345 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7346 "%s: TDLS mode is disabled OR not enabled in FW."
7347 MAC_ADDRESS_STR " action %d declined.",
7348 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007349 return -ENOTSUPP;
7350 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007351
Hoonki Lee27511902013-03-14 18:19:06 -07007352 /* other than teardown frame, other mgmt frames are not sent if disabled */
7353 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7354 {
7355 /* if tdls_mode is disabled to respond to peer's request */
7356 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7357 {
7358 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7359 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007360 " TDLS mode is disabled. action %d declined.",
7361 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007362
7363 return -ENOTSUPP;
7364 }
7365 }
7366
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007367 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7368 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007369 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007370 {
7371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007372 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007373 " TDLS setup is ongoing. action %d declined.",
7374 __func__, MAC_ADDR_ARRAY(peer), action_code);
7375 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007376 }
7377 }
7378
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007379 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7380 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007381 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007382 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007383 {
7384 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7385 we return error code at 'add_station()'. Hence we have this
7386 check again in addtion to add_station().
7387 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007388 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007389 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7391 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007392 " TDLS Max peer already connected. action %d declined.",
7393 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007394 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007395 }
7396 else
7397 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007398 /* maximum reached. tweak to send error code to peer and return
7399 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007400 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7402 "%s: " MAC_ADDRESS_STR
7403 " TDLS Max peer already connected send response status %d",
7404 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007405 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007406 /* fall through to send setup resp with failure status
7407 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007408 }
7409 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007410 else
7411 {
7412 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007413 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007414 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007415 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007417 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7418 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007419 return -EPERM;
7420 }
7421 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007422 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007423 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007424
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007425#ifdef WLAN_FEATURE_TDLS_DEBUG
7426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007427 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7428 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7429 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007430#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007431
Hoonki Leea34dd892013-02-05 22:56:02 -08007432 /*Except teardown responder will not be used so just make 0*/
7433 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007434 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007435 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007436
7437 hddTdlsPeer_t *pTdlsPeer;
7438 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7439
7440 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7441 responder = pTdlsPeer->is_responder;
7442 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007443 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7445 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7446 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7447 dialog_token, status_code, len);
7448 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007449 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007450 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007451
Hoonki Lee14621352013-04-16 17:51:19 -07007452 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7453 (SIR_MAC_TDLS_DIS_RSP == action_code))
7454 {
7455 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7456 {
7457 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7458 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7459 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7460 }
7461 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7462 }
7463
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007464 /* make sure doesn't call send_mgmt() while it is pending */
7465 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7466 {
7467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7468 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7469 __func__, MAC_ADDR_ARRAY(peer), action_code);
7470 return -EBUSY;
7471 }
7472
7473 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007474 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7475
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007476 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007477 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007478
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007479 if (VOS_STATUS_SUCCESS != status)
7480 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7482 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007483 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007484 wlan_hdd_tdls_check_bmps(pAdapter);
7485 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007486 }
7487
Hoonki Leed37cbb32013-04-20 00:31:14 -07007488 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7489 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7490
7491 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007492 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7494 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7495 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007496 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007497 wlan_hdd_tdls_check_bmps(pAdapter);
7498 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007499 }
7500
Gopichand Nakkala05922802013-03-14 12:23:19 -07007501 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007502 {
7503 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007504 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007505 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007506
Hoonki Leea34dd892013-02-05 22:56:02 -08007507 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7508 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007509 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007510 }
7511 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7512 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007513 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007514 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007515
7516 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007517error:
7518 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7519 because we already know that this transaction will be failed,
7520 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7521 to be safe, do not change the state mahine.
7522 */
7523 if(max_sta_failed == 0 &&
7524 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7525 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7526 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007527}
7528
7529static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7530 u8 *peer, enum nl80211_tdls_operation oper)
7531{
7532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7533 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307534 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307535#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7536 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307537 tANI_U8 staIdx;
7538#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007539#ifdef WLAN_FEATURE_TDLS_DEBUG
7540 const char *tdls_oper_str[]= {
7541 "NL80211_TDLS_DISCOVERY_REQ",
7542 "NL80211_TDLS_SETUP",
7543 "NL80211_TDLS_TEARDOWN",
7544 "NL80211_TDLS_ENABLE_LINK",
7545 "NL80211_TDLS_DISABLE_LINK",
7546 "NL80211_TDLS_UNKONW_OPER"};
7547#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007548 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007549
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007551 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007553 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007554 return -EINVAL;
7555 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007556
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307557 status = wlan_hdd_validate_context(pHddCtx);
7558
7559 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007560 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7562 "%s: HDD context is not valid", __func__);
7563 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007564 }
7565
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007566 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7567
7568 if ( NULL == pTdlsPeer ) {
7569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7570 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7571 return -EINVAL;
7572 }
7573
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007574#ifdef WLAN_FEATURE_TDLS_DEBUG
7575 if((int)oper > 4)
7576 oper = 5;
7577
7578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007579 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7580 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007581 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007582#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007583
7584 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007585 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007586 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007588 "TDLS Disabled in INI OR not enabled in FW. "
7589 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007590 return -ENOTSUPP;
7591 }
7592
7593 switch (oper) {
7594 case NL80211_TDLS_ENABLE_LINK:
7595 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007596 VOS_STATUS status;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307597 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007598
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007599 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7600 {
7601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7602 MAC_ADDRESS_STR " failed",
7603 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7604 return -EINVAL;
7605 }
7606
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007607 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007608 {
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307609 if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
7610 return -EINVAL;
7611 }
7612 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
7613
7614 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
7615 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
7616 /* Send TDLS peer UAPSD capabilities to the firmware and
7617 * register with the TL on after the response for this operation
7618 * is received .
7619 */
7620 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
7621 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
7622 if (status <= 0)
7623 {
7624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7625 "%s: Link Establish Request Faled Status %ld",
7626 __func__, status);
7627 return -EINVAL;
7628 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007629 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307630 /* Mark TDLS client Authenticated .*/
7631 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7632 pTdlsPeer->staId,
7633 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007634 if (VOS_STATUS_SUCCESS == status)
7635 {
Hoonki Lee14621352013-04-16 17:51:19 -07007636 if (pTdlsPeer->is_responder == 0)
7637 {
7638 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7639
7640 wlan_hdd_tdls_timer_restart(pAdapter,
7641 &pTdlsPeer->initiatorWaitTimeoutTimer,
7642 WAIT_TIME_TDLS_INITIATOR);
7643 /* suspend initiator TX until it receives direct packet from the
7644 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7645 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7646 &staId, NULL);
7647 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007648 wlan_hdd_tdls_increment_peer_count(pAdapter);
7649 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007650 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307651
7652 /* Update TL about the UAPSD masks , to route the packets to firmware */
7653 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7654 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VO )
7655 {
7656 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7657 pTdlsPeer->staId,
7658 WLANTL_AC_VO,
7659 7,
7660 7,
7661 0,
7662 0,
7663 WLANTL_BI_DIR );
7664
7665 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7666 }
7667
7668 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7669 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VI )
7670 {
7671 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7672 pTdlsPeer->staId,
7673 WLANTL_AC_VI,
7674 5,
7675 5,
7676 0,
7677 0,
7678 WLANTL_BI_DIR );
7679
7680 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7681 }
7682
7683 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7684 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BK )
7685 {
7686 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7687 pTdlsPeer->staId,
7688 WLANTL_AC_BK,
7689 2,
7690 2,
7691 0,
7692 0,
7693 WLANTL_BI_DIR );
7694
7695 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7696 }
7697
7698 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7699 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BE )
7700 {
7701 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7702 pTdlsPeer->staId,
7703 WLANTL_AC_BE,
7704 3,
7705 3,
7706 0,
7707 0,
7708 WLANTL_BI_DIR );
7709
7710 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7711 }
7712
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007713 }
7714
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007715 }
7716 break;
7717 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007718 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007719 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007720 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007721 long status;
7722
7723 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7724
Lee Hoonkic1262f22013-01-24 21:59:00 -08007725 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7726 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007727
7728 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7729 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7730 if (status <= 0)
7731 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007732 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7734 "%s: Del station failed status %ld",
7735 __func__, status);
7736 return -EPERM;
7737 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007738 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007739 }
7740 else
7741 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7743 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007744 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307745#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7746 if (pHddTdlsCtx->defer_link_lost_indication)
7747 {
7748 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7749 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7750 {
7751 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7752 if ( 0 != status)
7753 {
7754 hddLog(VOS_TRACE_LEVEL_ERROR,
7755 "%s wlan_hdd_disconnect failure, returned %d \n",
7756 __func__, (int)status );
7757 return -EINVAL;
7758 }
7759 }
7760 }
7761#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007762 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007763 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007764 case NL80211_TDLS_TEARDOWN:
7765 case NL80211_TDLS_SETUP:
7766 case NL80211_TDLS_DISCOVERY_REQ:
7767 /* We don't support in-driver setup/teardown/discovery */
7768 return -ENOTSUPP;
7769 default:
7770 return -ENOTSUPP;
7771 }
7772 return 0;
7773}
Chilam NG571c65a2013-01-19 12:27:36 +05307774
7775int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7776 struct net_device *dev, u8 *peer)
7777{
7778 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7779 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7780
7781 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7782 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7783}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007784#endif
7785
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307786#ifdef WLAN_FEATURE_GTK_OFFLOAD
7787/*
7788 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7789 * Callback rountine called upon receiving response for
7790 * get offload info
7791 */
7792void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7793 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7794{
7795
7796 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7797
7798 ENTER();
7799
7800 if (NULL == pAdapter)
7801 {
7802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7803 "%s: HDD adapter is Null", __func__);
7804 return ;
7805 }
7806
7807 if (NULL == pGtkOffloadGetInfoRsp)
7808 {
7809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7810 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7811 return ;
7812 }
7813
7814 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7815 {
7816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7817 "%s: wlan Failed to get replay counter value",
7818 __func__);
7819 return ;
7820 }
7821
7822 /* Update replay counter to NL */
7823 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7824 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7825}
7826
7827/*
7828 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7829 * This function is used to offload GTK rekeying job to the firmware.
7830 */
7831int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7832 struct cfg80211_gtk_rekey_data *data)
7833{
7834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7835 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7836 hdd_station_ctx_t *pHddStaCtx;
7837 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307838 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307839 tpSirGtkOffloadParams pGtkOffloadReqParams;
7840 eHalStatus status = eHAL_STATUS_FAILURE;
7841
7842 ENTER();
7843
7844 if (NULL == pAdapter)
7845 {
7846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7847 "%s: HDD adapter is Null", __func__);
7848 return -ENODEV;
7849 }
7850
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307851 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307852
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307853 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307854 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7856 "%s: HDD context is not valid", __func__);
7857 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307858 }
7859
7860 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7861 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7862 if (NULL == hHal)
7863 {
7864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7865 "%s: HAL context is Null!!!", __func__);
7866 return -EAGAIN;
7867 }
7868
7869 pGtkOffloadReqParams =
7870 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7871
7872 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7873 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7874 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7875 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7876 WNI_CFG_BSSID_LEN);
7877 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7878 sizeof (tANI_U64));
7879
7880 if (TRUE == pHddCtx->hdd_wlan_suspended)
7881 {
7882 /* if wlan is suspended, enable GTK offload directly from here */
7883 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7884 pAdapter->sessionId);
7885
7886 if (eHAL_STATUS_SUCCESS != status)
7887 {
7888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7889 "%s: sme_SetGTKOffload failed, returned %d",
7890 __func__, status);
7891 return status;
7892 }
7893 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7895 "%s: sme_SetGTKOffload successfull", __func__);
7896 }
7897 else
7898 {
7899 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7901 "%s: wlan not suspended GTKOffload request is stored",
7902 __func__);
7903 return eHAL_STATUS_SUCCESS;
7904 }
7905 return status;
7906}
7907#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7908
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307909/*
7910 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7911 * This function is used to set access control policy
7912 */
7913static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7914 struct net_device *dev, const struct cfg80211_acl_data *params)
7915{
7916 int i;
7917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7918 hdd_hostapd_state_t *pHostapdState;
7919 tsap_Config_t *pConfig;
7920 v_CONTEXT_t pVosContext = NULL;
7921 hdd_context_t *pHddCtx;
7922 int status;
7923
7924 ENTER();
7925
7926 if (NULL == pAdapter)
7927 {
7928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7929 "%s: HDD adapter is Null", __func__);
7930 return -ENODEV;
7931 }
7932
7933 if (NULL == params)
7934 {
7935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7936 "%s: params is Null", __func__);
7937 return -EINVAL;
7938 }
7939
7940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7941 status = wlan_hdd_validate_context(pHddCtx);
7942
7943 if (0 != status)
7944 {
7945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7946 "%s: HDD context is not valid", __func__);
7947 return status;
7948 }
7949
7950 pVosContext = pHddCtx->pvosContext;
7951 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7952
7953 if (NULL == pHostapdState)
7954 {
7955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7956 "%s: pHostapdState is Null", __func__);
7957 return -EINVAL;
7958 }
7959
7960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7961 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7962
7963 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7964 {
7965 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7966
7967 /* default value */
7968 pConfig->num_accept_mac = 0;
7969 pConfig->num_deny_mac = 0;
7970
7971 /**
7972 * access control policy
7973 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7974 * listed in hostapd.deny file.
7975 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7976 * listed in hostapd.accept file.
7977 */
7978 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7979 {
7980 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7981 }
7982 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
7983 {
7984 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7985 }
7986 else
7987 {
7988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7989 "%s:Acl Policy : %d is not supported",
7990 __func__, params->acl_policy);
7991 return -ENOTSUPP;
7992 }
7993
7994 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
7995 {
7996 pConfig->num_accept_mac = params->n_acl_entries;
7997 for (i = 0; i < params->n_acl_entries; i++)
7998 {
7999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8000 "** Add ACL MAC entry %i in WhiletList :"
8001 MAC_ADDRESS_STR, i,
8002 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8003
8004 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
8005 sizeof(qcmacaddr));
8006 }
8007 }
8008 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
8009 {
8010 pConfig->num_deny_mac = params->n_acl_entries;
8011 for (i = 0; i < params->n_acl_entries; i++)
8012 {
8013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8014 "** Add ACL MAC entry %i in BlackList :"
8015 MAC_ADDRESS_STR, i,
8016 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8017
8018 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
8019 sizeof(qcmacaddr));
8020 }
8021 }
8022
8023 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
8024 {
8025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8026 "%s: SAP Set Mac Acl fail", __func__);
8027 return -EINVAL;
8028 }
8029 }
8030 else
8031 {
8032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8033 "%s: Invalid device_mode = %d",
8034 __func__, pAdapter->device_mode);
8035 return -EINVAL;
8036 }
8037
8038 return 0;
8039}
8040
Jeff Johnson295189b2012-06-20 16:38:30 -07008041/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308042static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07008043{
8044 .add_virtual_intf = wlan_hdd_add_virtual_intf,
8045 .del_virtual_intf = wlan_hdd_del_virtual_intf,
8046 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
8047 .change_station = wlan_hdd_change_station,
8048#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8049 .add_beacon = wlan_hdd_cfg80211_add_beacon,
8050 .del_beacon = wlan_hdd_cfg80211_del_beacon,
8051 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008052#else
8053 .start_ap = wlan_hdd_cfg80211_start_ap,
8054 .change_beacon = wlan_hdd_cfg80211_change_beacon,
8055 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07008056#endif
8057 .change_bss = wlan_hdd_cfg80211_change_bss,
8058 .add_key = wlan_hdd_cfg80211_add_key,
8059 .get_key = wlan_hdd_cfg80211_get_key,
8060 .del_key = wlan_hdd_cfg80211_del_key,
8061 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008062#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008064#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 .scan = wlan_hdd_cfg80211_scan,
8066 .connect = wlan_hdd_cfg80211_connect,
8067 .disconnect = wlan_hdd_cfg80211_disconnect,
8068 .join_ibss = wlan_hdd_cfg80211_join_ibss,
8069 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
8070 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
8071 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
8072 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
8074 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
8075 .mgmt_tx = wlan_hdd_action,
8076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8077 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
8078 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
8079 .set_txq_params = wlan_hdd_set_txq_params,
8080#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 .get_station = wlan_hdd_cfg80211_get_station,
8082 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
8083 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008084 .add_station = wlan_hdd_cfg80211_add_station,
8085#ifdef FEATURE_WLAN_LFR
8086 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
8087 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
8088 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
8089#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008090#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8091 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8092#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008093#ifdef FEATURE_WLAN_TDLS
8094 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8095 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8096#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308097#ifdef WLAN_FEATURE_GTK_OFFLOAD
8098 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8099#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308100#ifdef FEATURE_WLAN_SCAN_PNO
8101 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8102 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8103#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308104 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008105};
8106