blob: 9564479571685aa0c1852dffc87bea944e668b79 [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;
1935 }
1936#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301937
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001938 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1939 {
1940 sme_SelectCBMode(hHal,
1941 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1942 pConfig->channel);
1943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001944 // ht_capab is not what the name conveys,this is used for protection bitmap
1945 pConfig->ht_capab =
1946 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1947
1948 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1949 {
1950 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1951 return -EINVAL;
1952 }
1953
1954 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301955 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1957 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301958 pConfig->obssProtEnabled =
1959 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001960
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301961 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001962 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301963 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1965 (int)pConfig->channel);
1966 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301967 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1968 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301970 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1972 pConfig->protEnabled, pConfig->obssProtEnabled);
1973
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301974 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001975 {
1976 //Bss already started. just return.
1977 //TODO Probably it should update some beacon params.
1978 hddLog( LOGE, "Bss Already started...Ignore the request");
1979 EXIT();
1980 return 0;
1981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301982
Jeff Johnson295189b2012-06-20 16:38:30 -07001983 pConfig->persona = pHostapdAdapter->device_mode;
1984
1985 pSapEventCallback = hdd_hostapd_SAPEventCB;
1986 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1987 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1988 {
1989 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1990 return -EINVAL;
1991 }
1992
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301993 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1995
1996 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301997
Jeff Johnson295189b2012-06-20 16:38:30 -07001998 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301999 {
2000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 ("ERROR: HDD vos wait for single_event failed!!\n"));
2002 VOS_ASSERT(0);
2003 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302004
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 //Succesfully started Bss update the state bit.
2006 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2007
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002008#ifdef WLAN_FEATURE_P2P_DEBUG
2009 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2010 {
2011 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2012 {
2013 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2014 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002015 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002016 }
2017 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2018 {
2019 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2020 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002021 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002022 }
2023 }
2024#endif
2025
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 pHostapdState->bCommit = TRUE;
2027 EXIT();
2028
2029 return 0;
2030}
2031
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002032#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302033static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2034 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 struct beacon_parameters *params)
2036{
2037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302038 hdd_context_t *pHddCtx;
2039 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002040
2041 ENTER();
2042
2043 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2044
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302045 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2046 status = wlan_hdd_validate_context(pHddCtx);
2047
2048 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002049 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2051 "%s: HDD context is not valid", __func__);
2052 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002053 }
2054
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302055 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 )
2058 {
2059 beacon_data_t *old,*new;
2060
2061 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302062
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 if (old)
2064 return -EALREADY;
2065
2066 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302068 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 {
2070 hddLog(VOS_TRACE_LEVEL_FATAL,
2071 "%s:Error!!! Allocating the new beacon\n",__func__);
2072 return -EINVAL;
2073 }
2074
2075 pAdapter->sessionCtx.ap.beacon = new;
2076
2077 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2078 }
2079
2080 EXIT();
2081 return status;
2082}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302083
2084static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 struct net_device *dev,
2086 struct beacon_parameters *params)
2087{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302089 hdd_context_t *pHddCtx;
2090 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002091
2092 ENTER();
2093
2094 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2095 __func__,pAdapter->device_mode);
2096
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2098 status = wlan_hdd_validate_context(pHddCtx);
2099
2100 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002101 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2103 "%s: HDD context is not valid", __func__);
2104 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002105 }
2106
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302109 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002110 {
2111 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302114
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 if (!old)
2116 return -ENOENT;
2117
2118 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2119
2120 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302121 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 "%s: Error!!! Allocating the new beacon\n",__func__);
2123 return -EINVAL;
2124 }
2125
2126 pAdapter->sessionCtx.ap.beacon = new;
2127
2128 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2129 }
2130
2131 EXIT();
2132 return status;
2133}
2134
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002135#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2136
2137#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002138static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2139 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002140#else
2141static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2142 struct net_device *dev)
2143#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002144{
2145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002146 hdd_context_t *pHddCtx = NULL;
2147 hdd_scaninfo_t *pScanInfo = NULL;
2148 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302149 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002150
2151 ENTER();
2152
2153 if (NULL == pAdapter)
2154 {
2155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002156 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 return -ENODEV;
2158 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002159
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2161 status = wlan_hdd_validate_context(pHddCtx);
2162
2163 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002164 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2166 "%s: HDD context is not valid", __func__);
2167 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002168 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002169
2170 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2171 if (NULL == staAdapter)
2172 {
2173 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2174 if (NULL == staAdapter)
2175 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002177 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002178 return -ENODEV;
2179 }
2180 }
2181
2182 pScanInfo = &pHddCtx->scan_info;
2183
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2185 __func__,pAdapter->device_mode);
2186
Jeff Johnsone7245742012-09-05 17:12:55 -07002187 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2188 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002189 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002190 hdd_abort_mac_scan(staAdapter->pHddCtx);
2191 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002192 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002193 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2194 if (!status)
2195 {
2196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002197 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002198 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002199 VOS_ASSERT(pScanInfo->mScanPending);
2200 return 0;
2201 }
2202 }
2203
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002206 )
2207 {
2208 beacon_data_t *old;
2209
2210 old = pAdapter->sessionCtx.ap.beacon;
2211
2212 if (!old)
2213 return -ENOENT;
2214
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002216
2217 mutex_lock(&pHddCtx->sap_lock);
2218 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2219 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002220 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 {
2222 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2223
2224 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2225
2226 if (!VOS_IS_STATUS_SUCCESS(status))
2227 {
2228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2229 ("ERROR: HDD vos wait for single_event failed!!\n"));
2230 VOS_ASSERT(0);
2231 }
2232 }
2233 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2234 }
2235 mutex_unlock(&pHddCtx->sap_lock);
2236
2237 if(status != VOS_STATUS_SUCCESS)
2238 {
2239 hddLog(VOS_TRACE_LEVEL_FATAL,
2240 "%s:Error!!! Stopping the BSS\n",__func__);
2241 return -EINVAL;
2242 }
2243
Jeff Johnson4416a782013-03-25 14:17:50 -07002244 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2246 ==eHAL_STATUS_FAILURE)
2247 {
2248 hddLog(LOGE,
2249 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2250 }
2251
Jeff Johnson4416a782013-03-25 14:17:50 -07002252 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2254 eANI_BOOLEAN_FALSE) )
2255 {
2256 hddLog(LOGE,
2257 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2258 }
2259
2260 // Reset WNI_CFG_PROBE_RSP Flags
2261 wlan_hdd_reset_prob_rspies(pAdapter);
2262
2263 pAdapter->sessionCtx.ap.beacon = NULL;
2264 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002265#ifdef WLAN_FEATURE_P2P_DEBUG
2266 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2267 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2268 {
2269 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2270 "GO got removed");
2271 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2272 }
2273#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 }
2275 EXIT();
2276 return status;
2277}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002278
2279#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2280
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302281static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2282 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002283 struct cfg80211_ap_settings *params)
2284{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302285 hdd_adapter_t *pAdapter;
2286 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302287 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002288
2289 ENTER();
2290
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302291 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002292 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302294 "%s: Device is Null", __func__);
2295 return -ENODEV;
2296 }
2297
2298 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2299 if (NULL == pAdapter)
2300 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302302 "%s: HDD adapter is Null", __func__);
2303 return -ENODEV;
2304 }
2305
2306 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
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 magic is invalid", __func__);
2310 return -ENODEV;
2311 }
2312
2313 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302314 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302315
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302316 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302317 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2319 "%s: HDD context is not valid", __func__);
2320 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302321 }
2322
2323 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2324 __func__, pAdapter->device_mode);
2325
2326 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002328 )
2329 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302330 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002331
2332 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302333
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002334 if (old)
2335 return -EALREADY;
2336
2337 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2338
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302339 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002340 {
2341 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302342 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002343 return -EINVAL;
2344 }
2345 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2347 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2348#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002349 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2350 params->ssid_len, params->hidden_ssid);
2351 }
2352
2353 EXIT();
2354 return status;
2355}
2356
2357
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302358static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002359 struct net_device *dev,
2360 struct cfg80211_beacon_data *params)
2361{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302362 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302363 hdd_context_t *pHddCtx;
2364 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002365
2366 ENTER();
2367
2368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2369 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302370
2371 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2372 status = wlan_hdd_validate_context(pHddCtx);
2373
2374 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "%s: HDD context is not valid", __func__);
2378 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002379 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002380
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302381 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002382 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302383 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002384 {
2385 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302386
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002387 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302388
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002389 if (!old)
2390 return -ENOENT;
2391
2392 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2393
2394 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302395 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396 "%s: Error!!! Allocating the new beacon\n",__func__);
2397 return -EINVAL;
2398 }
2399
2400 pAdapter->sessionCtx.ap.beacon = new;
2401
2402 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2403 }
2404
2405 EXIT();
2406 return status;
2407}
2408
2409#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2410
Jeff Johnson295189b2012-06-20 16:38:30 -07002411
2412static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2413 struct net_device *dev,
2414 struct bss_parameters *params)
2415{
2416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2417
2418 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302419
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2421 __func__,pAdapter->device_mode);
2422
2423 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002424 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302425 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002426 {
2427 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2428 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302429 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002430 {
2431 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302432 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002433 }
2434
2435 EXIT();
2436 return 0;
2437}
2438
2439/*
2440 * FUNCTION: wlan_hdd_cfg80211_change_iface
2441 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2442 */
2443int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2444 struct net_device *ndev,
2445 enum nl80211_iftype type,
2446 u32 *flags,
2447 struct vif_params *params
2448 )
2449{
2450 struct wireless_dev *wdev;
2451 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002453 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002454 tCsrRoamProfile *pRoamProfile = NULL;
2455 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302456 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002457 eMib_dot11DesiredBssType connectedBssType;
2458 VOS_STATUS status;
2459
2460 ENTER();
2461
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302462 status = wlan_hdd_validate_context(pHddCtx);
2463
2464 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: HDD context is not valid", __func__);
2468 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002469 }
2470
2471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2472 __func__, pAdapter->device_mode);
2473
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302474 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002475 wdev = ndev->ieee80211_ptr;
2476
2477#ifdef WLAN_BTAMP_FEATURE
2478 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2479 (NL80211_IFTYPE_ADHOC == type)||
2480 (NL80211_IFTYPE_AP == type)||
2481 (NL80211_IFTYPE_P2P_GO == type))
2482 {
2483 pHddCtx->isAmpAllowed = VOS_FALSE;
2484 // stop AMP traffic
2485 status = WLANBAP_StopAmp();
2486 if(VOS_STATUS_SUCCESS != status )
2487 {
2488 pHddCtx->isAmpAllowed = VOS_TRUE;
2489 hddLog(VOS_TRACE_LEVEL_FATAL,
2490 "%s: Failed to stop AMP", __func__);
2491 return -EINVAL;
2492 }
2493 }
2494#endif //WLAN_BTAMP_FEATURE
2495 /* Reset the current device mode bit mask*/
2496 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2497
2498 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002500 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002501 )
2502 {
2503 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2504 pRoamProfile = &pWextState->roamProfile;
2505 LastBSSType = pRoamProfile->BSSType;
2506
2507 switch (type)
2508 {
2509 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002510 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 hddLog(VOS_TRACE_LEVEL_INFO,
2512 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2513 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002514#ifdef WLAN_FEATURE_11AC
2515 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2516 {
2517 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2518 }
2519#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302520 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002521 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002522 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002523 //Check for sub-string p2p to confirm its a p2p interface
2524 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302525 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002526 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2527 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2528 }
2529 else
2530 {
2531 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002534 break;
2535 case NL80211_IFTYPE_ADHOC:
2536 hddLog(VOS_TRACE_LEVEL_INFO,
2537 "%s: setting interface Type to ADHOC", __func__);
2538 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2539 pRoamProfile->phyMode =
2540 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002541 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 wdev->iftype = type;
2543 break;
2544
2545 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 {
2548 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2549 "%s: setting interface Type to %s", __func__,
2550 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2551
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002552 //Cancel any remain on channel for GO mode
2553 if (NL80211_IFTYPE_P2P_GO == type)
2554 {
2555 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2556 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002557 if (NL80211_IFTYPE_AP == type)
2558 {
2559 /* As Loading WLAN Driver one interface being created for p2p device
2560 * address. This will take one HW STA and the max number of clients
2561 * that can connect to softAP will be reduced by one. so while changing
2562 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2563 * interface as it is not required in SoftAP mode.
2564 */
2565
2566 // Get P2P Adapter
2567 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2568
2569 if (pP2pAdapter)
2570 {
2571 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2572 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2573 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2574 }
2575 }
2576
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 //De-init the adapter.
2578 hdd_stop_adapter( pHddCtx, pAdapter );
2579 hdd_deinit_adapter( pHddCtx, pAdapter );
2580 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002581 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2582 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002583
2584 //Disable BMPS and IMPS if enabled
2585 //before starting Go
2586 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2587 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302588 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002589 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2590 {
2591 //Fail to Exit BMPS
2592 VOS_ASSERT(0);
2593 }
2594 }
2595
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002596 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2597 (pConfig->apRandomBssidEnabled))
2598 {
2599 /* To meet Android requirements create a randomized
2600 MAC address of the form 02:1A:11:Fx:xx:xx */
2601 get_random_bytes(&ndev->dev_addr[3], 3);
2602 ndev->dev_addr[0] = 0x02;
2603 ndev->dev_addr[1] = 0x1A;
2604 ndev->dev_addr[2] = 0x11;
2605 ndev->dev_addr[3] |= 0xF0;
2606 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2607 VOS_MAC_ADDR_SIZE);
2608 pr_info("wlan: Generated HotSpot BSSID "
2609 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2610 ndev->dev_addr[0],
2611 ndev->dev_addr[1],
2612 ndev->dev_addr[2],
2613 ndev->dev_addr[3],
2614 ndev->dev_addr[4],
2615 ndev->dev_addr[5]);
2616 }
2617
Jeff Johnson295189b2012-06-20 16:38:30 -07002618 hdd_set_ap_ops( pAdapter->dev );
2619
2620 status = hdd_init_ap_mode(pAdapter);
2621 if(status != VOS_STATUS_SUCCESS)
2622 {
2623 hddLog(VOS_TRACE_LEVEL_FATAL,
2624 "%s: Error initializing the ap mode", __func__);
2625 return -EINVAL;
2626 }
2627 hdd_set_conparam(1);
2628
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 /*interface type changed update in wiphy structure*/
2630 if(wdev)
2631 {
2632 wdev->iftype = type;
2633 pHddCtx->change_iface = type;
2634 }
2635 else
2636 {
2637 hddLog(VOS_TRACE_LEVEL_ERROR,
2638 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2639 return -EINVAL;
2640 }
2641 goto done;
2642 }
2643
2644 default:
2645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2646 __func__);
2647 return -EOPNOTSUPP;
2648 }
2649 }
2650 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002651 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002652 )
2653 {
2654 switch(type)
2655 {
2656 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002659 hdd_stop_adapter( pHddCtx, pAdapter );
2660 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002661 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002662 //Check for sub-string p2p to confirm its a p2p interface
2663 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002664 {
2665 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2666 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2667 }
2668 else
2669 {
2670 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002673 hdd_set_conparam(0);
2674 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2676 hdd_set_station_ops( pAdapter->dev );
2677 status = hdd_init_station_mode( pAdapter );
2678 if( VOS_STATUS_SUCCESS != status )
2679 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002680 /* In case of JB, for P2P-GO, only change interface will be called,
2681 * This is the right place to enable back bmps_imps()
2682 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302683 if (pHddCtx->hdd_wlan_suspended)
2684 {
2685 hdd_set_pwrparams(pHddCtx);
2686 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002687 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002688 goto done;
2689 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002691 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002692 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2693 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 goto done;
2695 default:
2696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2697 __func__);
2698 return -EOPNOTSUPP;
2699
2700 }
2701
2702 }
2703 else
2704 {
2705 return -EOPNOTSUPP;
2706 }
2707
2708
2709 if(pRoamProfile)
2710 {
2711 if ( LastBSSType != pRoamProfile->BSSType )
2712 {
2713 /*interface type changed update in wiphy structure*/
2714 wdev->iftype = type;
2715
2716 /*the BSS mode changed, We need to issue disconnect
2717 if connected or in IBSS disconnect state*/
2718 if ( hdd_connGetConnectedBssType(
2719 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2720 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2721 {
2722 /*need to issue a disconnect to CSR.*/
2723 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2724 if( eHAL_STATUS_SUCCESS ==
2725 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2726 pAdapter->sessionId,
2727 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2728 {
2729 wait_for_completion_interruptible_timeout(
2730 &pAdapter->disconnect_comp_var,
2731 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2732 }
2733 }
2734 }
2735 }
2736
2737done:
2738 /*set bitmask based on updated value*/
2739 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2740#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302741 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002742 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2743 {
2744 //we are ok to do AMP
2745 pHddCtx->isAmpAllowed = VOS_TRUE;
2746 }
2747#endif //WLAN_BTAMP_FEATURE
2748 EXIT();
2749 return 0;
2750}
2751
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002752#ifdef FEATURE_WLAN_TDLS
2753static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2754 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2755{
2756 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2757 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2758 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002759 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002760
2761 ENTER();
2762
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302763 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002764 {
2765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2766 "Invalid arguments");
2767 return -EINVAL;
2768 }
Hoonki Lee27511902013-03-14 18:19:06 -07002769
2770 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2771 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2772 {
2773 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2774 "%s: TDLS mode is disabled OR not enabled in FW."
2775 MAC_ADDRESS_STR " Request declined.",
2776 __func__, MAC_ADDR_ARRAY(mac));
2777 return -ENOTSUPP;
2778 }
2779
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002780 if (pHddCtx->isLogpInProgress)
2781 {
2782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2783 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002784 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002785 return -EBUSY;
2786 }
2787
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002788 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2789
2790 if ( NULL == pTdlsPeer ) {
2791 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2792 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2793 __func__, MAC_ADDR_ARRAY(mac), update);
2794 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002795 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002796
2797 /* in add station, we accept existing valid staId if there is */
2798 if ((0 == update) &&
2799 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2800 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002801 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002802 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002803 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002804 " link_status %d. staId %d. add station ignored.",
2805 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2806 return 0;
2807 }
2808 /* in change station, we accept only when staId is valid */
2809 if ((1 == update) &&
2810 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2811 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2812 {
2813 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2814 "%s: " MAC_ADDRESS_STR
2815 " link status %d. staId %d. change station %s.",
2816 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2817 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2818 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002819 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002820
2821 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002822 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002823 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2825 "%s: " MAC_ADDRESS_STR
2826 " TDLS setup is ongoing. Request declined.",
2827 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002828 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002829 }
2830
2831 /* first to check if we reached to maximum supported TDLS peer.
2832 TODO: for now, return -EPERM looks working fine,
2833 but need to check if any other errno fit into this category.*/
2834 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2835 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2837 "%s: " MAC_ADDRESS_STR
2838 " TDLS Max peer already connected. Request declined.",
2839 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002840 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002841 }
2842 else
2843 {
2844 hddTdlsPeer_t *pTdlsPeer;
2845 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002846 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002847 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2849 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2850 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002851 return -EPERM;
2852 }
2853 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002854 if (0 == update)
2855 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002856
Jeff Johnsond75fe012013-04-06 10:53:06 -07002857 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302858 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002859 {
2860 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2861 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002862 if(StaParams->htcap_present)
2863 {
2864 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2865 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2866 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2867 "ht_capa->extended_capabilities: %0x",
2868 StaParams->HTCap.extendedHtCapInfo);
2869 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002870 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2871 "params->capability: %0x",StaParams->capability);
2872 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2873 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002874 if(StaParams->vhtcap_present)
2875 {
2876 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2877 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2878 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2879 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2880 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002881 {
2882 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002884 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2885 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2886 "[%d]: %x ", i, StaParams->supported_rates[i]);
2887 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002888 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302889 else if ((1 == update) && (NULL == StaParams))
2890 {
2891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2892 "%s : update is true, but staParams is NULL. Error!", __func__);
2893 return -EPERM;
2894 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002895
2896 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2897
2898 if (!update)
2899 {
2900 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2901 pAdapter->sessionId, mac);
2902 }
2903 else
2904 {
2905 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2906 pAdapter->sessionId, mac, StaParams);
2907 }
2908
2909 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2910 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2911
2912 if (!status)
2913 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002915 "%s: timeout waiting for tdls add station indication",
2916 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002917 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002918 }
2919 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
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: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002923 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002924 }
2925
2926 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002927
2928error:
2929 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2930 return -EPERM;
2931
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002932}
2933#endif
2934
Jeff Johnson295189b2012-06-20 16:38:30 -07002935static int wlan_hdd_change_station(struct wiphy *wiphy,
2936 struct net_device *dev,
2937 u8 *mac,
2938 struct station_parameters *params)
2939{
2940 VOS_STATUS status = VOS_STATUS_SUCCESS;
2941 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302942 hdd_context_t *pHddCtx;
2943 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002944 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002945#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002946 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002947 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002948#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002949 ENTER();
2950
Gopichand Nakkala29149562013-05-10 21:43:41 +05302951 if ((NULL == pAdapter))
2952 {
2953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2954 "invalid adapter ");
2955 return -EINVAL;
2956 }
2957
2958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2959 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2960
2961 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2962 {
2963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2964 "invalid HDD state or HDD station context");
2965 return -EINVAL;
2966 }
2967
2968 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002969 {
2970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2971 "%s:LOGP in Progress. Ignore!!!", __func__);
2972 return -EAGAIN;
2973 }
2974
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2976
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002977 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2978 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002979 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002980 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302982 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 WLANTL_STA_AUTHENTICATED);
2984
Gopichand Nakkala29149562013-05-10 21:43:41 +05302985 if (status != VOS_STATUS_SUCCESS)
2986 {
2987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2988 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2989 return -EINVAL;
2990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 }
2992 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002993 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2994 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302995#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002996 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2997 StaParams.capability = params->capability;
2998 StaParams.uapsd_queues = params->uapsd_queues;
2999 StaParams.max_sp = params->max_sp;
3000
3001 if (0 != params->ext_capab_len)
3002 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3003 sizeof(StaParams.extn_capability));
3004
3005 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003006 {
3007 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003008 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003009 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003010
3011 StaParams.supported_rates_len = params->supported_rates_len;
3012
3013 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3014 * The supported_rates array , for all the structures propogating till Add Sta
3015 * to the firmware has to be modified , if the supplicant (ieee80211) is
3016 * modified to send more rates.
3017 */
3018
3019 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3020 */
3021 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3022 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3023
3024 if (0 != StaParams.supported_rates_len) {
3025 int i = 0;
3026 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3027 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003029 "Supported Rates with Length %d", StaParams.supported_rates_len);
3030 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003032 "[%d]: %0x", i, StaParams.supported_rates[i]);
3033 }
3034
3035 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003036 {
3037 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003038 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003039 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003040
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003041 if (0 != params->ext_capab_len ) {
3042 /*Define A Macro : TODO Sunil*/
3043 if ((1<<4) & StaParams.extn_capability[3]) {
3044 isBufSta = 1;
3045 }
3046 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303047 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3048 params->max_sp, isBufSta);
3049 if (VOS_STATUS_SUCCESS != status) {
3050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3051 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3052 return -EINVAL;
3053 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003054 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3055
3056 if (VOS_STATUS_SUCCESS != status) {
3057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3058 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3059 return -EINVAL;
3060 }
3061 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003062#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303063 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3064 {
3065 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3066 WLANTL_STA_AUTHENTICATED);
3067 if (status != VOS_STATUS_SUCCESS)
3068 {
3069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3070 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3071 return -EINVAL;
3072 }
3073 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3075 "%s: TL Moving to Authenticated state", __func__);
3076 }
3077 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303078
Jeff Johnsone7245742012-09-05 17:12:55 -07003079 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 return status;
3081}
3082
3083/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 * FUNCTION: wlan_hdd_cfg80211_add_key
3085 * This function is used to initialize the key information
3086 */
3087#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003088static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 struct net_device *ndev,
3090 u8 key_index, bool pairwise,
3091 const u8 *mac_addr,
3092 struct key_params *params
3093 )
3094#else
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, const u8 *mac_addr,
3098 struct key_params *params
3099 )
3100#endif
3101{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 tCsrRoamSetKey setKey;
3104 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303105 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003106 v_U32_t roamId= 0xFF;
3107 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 hdd_hostapd_state_t *pHostapdState;
3109 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003110 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303111 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003112
3113 ENTER();
3114
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303115 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3116 status = wlan_hdd_validate_context(pHddCtx);
3117
3118 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003119 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3121 "%s: HDD context is not valid", __func__);
3122 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003123 }
3124
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003125 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3126 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003127
3128 if (CSR_MAX_NUM_KEY <= key_index)
3129 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003131 key_index);
3132
3133 return -EINVAL;
3134 }
3135
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003136 if (CSR_MAX_KEY_LEN < params->key_len)
3137 {
3138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3139 params->key_len);
3140
3141 return -EINVAL;
3142 }
3143
3144 hddLog(VOS_TRACE_LEVEL_INFO,
3145 "%s: called with key index = %d & key length %d",
3146 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003147
3148 /*extract key idx, key len and key*/
3149 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3150 setKey.keyId = key_index;
3151 setKey.keyLength = params->key_len;
3152 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3153
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003154 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 {
3156 case WLAN_CIPHER_SUITE_WEP40:
3157 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3158 break;
3159
3160 case WLAN_CIPHER_SUITE_WEP104:
3161 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3162 break;
3163
3164 case WLAN_CIPHER_SUITE_TKIP:
3165 {
3166 u8 *pKey = &setKey.Key[0];
3167 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3168
3169 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3170
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003171 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003172
3173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 |--------------|----------|----------|
3176 <---16bytes---><--8bytes--><--8bytes-->
3177
3178 */
3179 /*Sme expects the 32 bytes key to be in the below order
3180
3181 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 |--------------|----------|----------|
3184 <---16bytes---><--8bytes--><--8bytes-->
3185 */
3186 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003187 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003188
3189 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003190 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003191
3192 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003193 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003194
3195
3196 break;
3197 }
3198
3199 case WLAN_CIPHER_SUITE_CCMP:
3200 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3201 break;
3202
3203#ifdef FEATURE_WLAN_WAPI
3204 case WLAN_CIPHER_SUITE_SMS4:
3205 {
3206 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3207 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3208 params->key, params->key_len);
3209 return 0;
3210 }
3211#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003212
Jeff Johnson295189b2012-06-20 16:38:30 -07003213#ifdef FEATURE_WLAN_CCX
3214 case WLAN_CIPHER_SUITE_KRK:
3215 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3216 break;
3217#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003218
3219#ifdef WLAN_FEATURE_11W
3220 case WLAN_CIPHER_SUITE_AES_CMAC:
3221 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003222 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003223#endif
3224
Jeff Johnson295189b2012-06-20 16:38:30 -07003225 default:
3226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3227 __func__, params->cipher);
3228 return -EOPNOTSUPP;
3229 }
3230
3231 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3232 __func__, setKey.encType);
3233
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003234 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3236 (!pairwise)
3237#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003238 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003239#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003240 )
3241 {
3242 /* set group key*/
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3244 "%s- %d: setting Broadcast key",
3245 __func__, __LINE__);
3246 setKey.keyDirection = eSIR_RX_ONLY;
3247 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3248 }
3249 else
3250 {
3251 /* set pairwise key*/
3252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3253 "%s- %d: setting pairwise key",
3254 __func__, __LINE__);
3255 setKey.keyDirection = eSIR_TX_RX;
3256 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3257 }
3258 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3259 {
3260 setKey.keyDirection = eSIR_TX_RX;
3261 /*Set the group key*/
3262 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3263 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003264
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003265 if ( 0 != status )
3266 {
3267 hddLog(VOS_TRACE_LEVEL_ERROR,
3268 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3269 return -EINVAL;
3270 }
3271 /*Save the keys here and call sme_RoamSetKey for setting
3272 the PTK after peer joins the IBSS network*/
3273 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3274 &setKey, sizeof(tCsrRoamSetKey));
3275 return status;
3276 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303277 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3278 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3279 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003280 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003281 if( pHostapdState->bssState == BSS_START )
3282 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003283 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3284
3285 if ( status != eHAL_STATUS_SUCCESS )
3286 {
3287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3288 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3289 __LINE__, status );
3290 }
3291 }
3292
3293 /* Saving WEP keys */
3294 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3295 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3296 {
3297 //Save the wep key in ap context. Issue setkey after the BSS is started.
3298 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3299 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3300 }
3301 else
3302 {
3303 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003304 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003305 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3306 }
3307 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003308 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3309 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003310 {
3311 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3312 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3313
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3315 if (!pairwise)
3316#else
3317 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3318#endif
3319 {
3320 /* set group key*/
3321 if (pHddStaCtx->roam_info.deferKeyComplete)
3322 {
3323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3324 "%s- %d: Perform Set key Complete",
3325 __func__, __LINE__);
3326 hdd_PerformRoamSetKeyComplete(pAdapter);
3327 }
3328 }
3329
Jeff Johnson295189b2012-06-20 16:38:30 -07003330 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3331
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003332 pWextState->roamProfile.Keys.defaultIndex = key_index;
3333
3334
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003335 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003336 params->key, params->key_len);
3337
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303338
Jeff Johnson295189b2012-06-20 16:38:30 -07003339 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3340
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303341 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003342 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303343 __func__, setKey.peerMac[0], setKey.peerMac[1],
3344 setKey.peerMac[2], setKey.peerMac[3],
3345 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003346 setKey.keyDirection);
3347
3348 vos_status = wlan_hdd_check_ula_done(pAdapter);
3349
3350 if ( vos_status != VOS_STATUS_SUCCESS )
3351 {
3352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3353 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3354 __LINE__, vos_status );
3355
3356 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3357
3358 return -EINVAL;
3359
3360 }
3361
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003362#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303363 /* The supplicant may attempt to set the PTK once pre-authentication
3364 is done. Save the key in the UMAC and include it in the ADD BSS
3365 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003366 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303367 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003368 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303369 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3370 "%s: Update PreAuth Key success", __func__);
3371 return 0;
3372 }
3373 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3374 {
3375 hddLog(VOS_TRACE_LEVEL_ERROR,
3376 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303377 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003378 }
3379#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003380
3381 /* issue set key request to SME*/
3382 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3383 pAdapter->sessionId, &setKey, &roamId );
3384
3385 if ( 0 != status )
3386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303387 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3389 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3390 return -EINVAL;
3391 }
3392
3393
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303394 /* in case of IBSS as there was no information available about WEP keys during
3395 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003396 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303397 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3398 !( ( IW_AUTH_KEY_MGMT_802_1X
3399 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003400 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3401 )
3402 &&
3403 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3404 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3405 )
3406 )
3407 {
3408 setKey.keyDirection = eSIR_RX_ONLY;
3409 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3410
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303411 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303413 __func__, setKey.peerMac[0], setKey.peerMac[1],
3414 setKey.peerMac[2], setKey.peerMac[3],
3415 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003416 setKey.keyDirection);
3417
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303418 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003419 pAdapter->sessionId, &setKey, &roamId );
3420
3421 if ( 0 != status )
3422 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303423 hddLog(VOS_TRACE_LEVEL_ERROR,
3424 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003425 __func__, status);
3426 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3427 return -EINVAL;
3428 }
3429 }
3430 }
3431
3432 return 0;
3433}
3434
3435/*
3436 * FUNCTION: wlan_hdd_cfg80211_get_key
3437 * This function is used to get the key information
3438 */
3439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303440static int wlan_hdd_cfg80211_get_key(
3441 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003442 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303443 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003444 const u8 *mac_addr, void *cookie,
3445 void (*callback)(void *cookie, struct key_params*)
3446 )
3447#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303448static int wlan_hdd_cfg80211_get_key(
3449 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003450 struct net_device *ndev,
3451 u8 key_index, const u8 *mac_addr, void *cookie,
3452 void (*callback)(void *cookie, struct key_params*)
3453 )
3454#endif
3455{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003457 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3458 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3459 struct key_params params;
3460
3461 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303462
Jeff Johnson295189b2012-06-20 16:38:30 -07003463 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3464 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303465
Jeff Johnson295189b2012-06-20 16:38:30 -07003466 memset(&params, 0, sizeof(params));
3467
3468 if (CSR_MAX_NUM_KEY <= key_index)
3469 {
3470 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303471 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003472
3473 switch(pRoamProfile->EncryptionType.encryptionType[0])
3474 {
3475 case eCSR_ENCRYPT_TYPE_NONE:
3476 params.cipher = IW_AUTH_CIPHER_NONE;
3477 break;
3478
3479 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3480 case eCSR_ENCRYPT_TYPE_WEP40:
3481 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3482 break;
3483
3484 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3485 case eCSR_ENCRYPT_TYPE_WEP104:
3486 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3487 break;
3488
3489 case eCSR_ENCRYPT_TYPE_TKIP:
3490 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3491 break;
3492
3493 case eCSR_ENCRYPT_TYPE_AES:
3494 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3495 break;
3496
3497 default:
3498 params.cipher = IW_AUTH_CIPHER_NONE;
3499 break;
3500 }
3501
3502 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3503 params.seq_len = 0;
3504 params.seq = NULL;
3505 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3506 callback(cookie, &params);
3507 return 0;
3508}
3509
3510/*
3511 * FUNCTION: wlan_hdd_cfg80211_del_key
3512 * This function is used to delete the key information
3513 */
3514#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303515static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303517 u8 key_index,
3518 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003519 const u8 *mac_addr
3520 )
3521#else
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,
3524 u8 key_index,
3525 const u8 *mac_addr
3526 )
3527#endif
3528{
3529 int status = 0;
3530
3531 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303532 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003533 //it is observed that this is invalidating peer
3534 //key index whenever re-key is done. This is affecting data link.
3535 //It should be ok to ignore del_key.
3536#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3538 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003539 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3540 tCsrRoamSetKey setKey;
3541 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303542
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 ENTER();
3544
3545 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3546 __func__,pAdapter->device_mode);
3547
3548 if (CSR_MAX_NUM_KEY <= key_index)
3549 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003551 key_index);
3552
3553 return -EINVAL;
3554 }
3555
3556 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3557 setKey.keyId = key_index;
3558
3559 if (mac_addr)
3560 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3561 else
3562 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3563
3564 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3565
3566 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003567 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303568 )
3569 {
3570
3571 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003572 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3573 if( pHostapdState->bssState == BSS_START)
3574 {
3575 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303576
Jeff Johnson295189b2012-06-20 16:38:30 -07003577 if ( status != eHAL_STATUS_SUCCESS )
3578 {
3579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3580 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3581 __LINE__, status );
3582 }
3583 }
3584 }
3585 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303586 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 )
3588 {
3589 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3590
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303591 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3592
3593 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595 __func__, setKey.peerMac[0], setKey.peerMac[1],
3596 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598 if(pAdapter->sessionCtx.station.conn_info.connState ==
3599 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303601 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303603
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 if ( 0 != status )
3605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303606 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 "%s: sme_RoamSetKey failure, returned %d",
3608 __func__, status);
3609 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3610 return -EINVAL;
3611 }
3612 }
3613 }
3614#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003615 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003616 return status;
3617}
3618
3619/*
3620 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3621 * This function is used to set the default tx key index
3622 */
3623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3624static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3625 struct net_device *ndev,
3626 u8 key_index,
3627 bool unicast, bool multicast)
3628#else
3629static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3630 struct net_device *ndev,
3631 u8 key_index)
3632#endif
3633{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303635 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303636 hdd_wext_state_t *pWextState;
3637 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303638 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003639
3640 ENTER();
3641
Gopichand Nakkala29149562013-05-10 21:43:41 +05303642 if ((NULL == pAdapter))
3643 {
3644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3645 "invalid adapter");
3646 return -EINVAL;
3647 }
3648
3649 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3650 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3651
3652 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3653 {
3654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3655 "invalid Wext state or HDD context");
3656 return -EINVAL;
3657 }
3658
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3660 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303661
Jeff Johnson295189b2012-06-20 16:38:30 -07003662 if (CSR_MAX_NUM_KEY <= key_index)
3663 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 key_index);
3666
3667 return -EINVAL;
3668 }
3669
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303670 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3671 status = wlan_hdd_validate_context(pHddCtx);
3672
3673 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003674 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3676 "%s: HDD context is not valid", __func__);
3677 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003678 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303679
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003681 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303682 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303684 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303686 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003687 pWextState->roamProfile.EncryptionType.encryptionType[0])
3688 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303689 {
3690 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003691 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303692
Jeff Johnson295189b2012-06-20 16:38:30 -07003693 tCsrRoamSetKey setKey;
3694 v_U32_t roamId= 0xFF;
3695 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696
3697 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303699
Jeff Johnson295189b2012-06-20 16:38:30 -07003700 Keys->defaultIndex = (u8)key_index;
3701 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3702 setKey.keyId = key_index;
3703 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303704
3705 vos_mem_copy(&setKey.Key[0],
3706 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303708
Gopichand Nakkala29149562013-05-10 21:43:41 +05303709 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303710
3711 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003712 &pHddStaCtx->conn_info.bssId[0],
3713 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303714
Gopichand Nakkala29149562013-05-10 21:43:41 +05303715 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3716 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3717 eCSR_ENCRYPT_TYPE_WEP104)
3718 {
3719 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3720 even though ap is configured for WEP-40 encryption. In this canse the key length
3721 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3722 type(104) and switching encryption type to 40*/
3723 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3724 eCSR_ENCRYPT_TYPE_WEP40;
3725 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3726 eCSR_ENCRYPT_TYPE_WEP40;
3727 }
3728
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303729 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303731
Jeff Johnson295189b2012-06-20 16:38:30 -07003732 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303733 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003734 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303735
Jeff Johnson295189b2012-06-20 16:38:30 -07003736 if ( 0 != status )
3737 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303738 hddLog(VOS_TRACE_LEVEL_ERROR,
3739 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 status);
3741 return -EINVAL;
3742 }
3743 }
3744 }
3745
3746 /* In SoftAp mode setting key direction for default mode */
3747 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3748 {
3749 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3750 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3751 (eCSR_ENCRYPT_TYPE_AES !=
3752 pWextState->roamProfile.EncryptionType.encryptionType[0])
3753 )
3754 {
3755 /* Saving key direction for default key index to TX default */
3756 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3757 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3758 }
3759 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303760
Jeff Johnson295189b2012-06-20 16:38:30 -07003761 return status;
3762}
3763
Jeff Johnson295189b2012-06-20 16:38:30 -07003764/*
3765 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3766 * This function is used to inform the BSS details to nl80211 interface.
3767 */
3768static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3769 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3770{
3771 struct net_device *dev = pAdapter->dev;
3772 struct wireless_dev *wdev = dev->ieee80211_ptr;
3773 struct wiphy *wiphy = wdev->wiphy;
3774 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3775 int chan_no;
3776 int ie_length;
3777 const char *ie;
3778 unsigned int freq;
3779 struct ieee80211_channel *chan;
3780 int rssi = 0;
3781 struct cfg80211_bss *bss = NULL;
3782
3783 ENTER();
3784
3785 if( NULL == pBssDesc )
3786 {
3787 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3788 return bss;
3789 }
3790
3791 chan_no = pBssDesc->channelId;
3792 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3793 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3794
3795 if( NULL == ie )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3798 return bss;
3799 }
3800
3801#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3802 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3803 {
3804 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3805 }
3806 else
3807 {
3808 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3809 }
3810#else
3811 freq = ieee80211_channel_to_frequency(chan_no);
3812#endif
3813
3814 chan = __ieee80211_get_channel(wiphy, freq);
3815
3816 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3817 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3818 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3819 if (bss == NULL)
3820 {
3821 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3822
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303823 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3824 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003825 pBssDesc->capabilityInfo,
3826 pBssDesc->beaconInterval, ie, ie_length,
3827 rssi, GFP_KERNEL ));
3828}
3829 else
3830 {
3831 return bss;
3832 }
3833}
3834
3835
3836
3837/*
3838 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3839 * This function is used to inform the BSS details to nl80211 interface.
3840 */
3841struct cfg80211_bss*
3842wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3843 tSirBssDescription *bss_desc
3844 )
3845{
3846 /*
3847 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3848 already exists in bss data base of cfg80211 for that particular BSS ID.
3849 Using cfg80211_inform_bss_frame to update the bss entry instead of
3850 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3851 now there is no possibility to get the mgmt(probe response) frame from PE,
3852 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3853 cfg80211_inform_bss_frame.
3854 */
3855 struct net_device *dev = pAdapter->dev;
3856 struct wireless_dev *wdev = dev->ieee80211_ptr;
3857 struct wiphy *wiphy = wdev->wiphy;
3858 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003859#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3860 qcom_ie_age *qie_age = NULL;
3861 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3862#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003863 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003864#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003865 const char *ie =
3866 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3867 unsigned int freq;
3868 struct ieee80211_channel *chan;
3869 struct ieee80211_mgmt *mgmt =
3870 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3871 struct cfg80211_bss *bss_status = NULL;
3872 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3873 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003874#ifdef WLAN_OPEN_SOURCE
3875 struct timespec ts;
3876#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003877
3878 ENTER();
3879
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003880 if (!mgmt)
3881 return NULL;
3882
Jeff Johnson295189b2012-06-20 16:38:30 -07003883 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003884
3885#ifdef WLAN_OPEN_SOURCE
3886 /* Android does not want the timestamp from the frame.
3887 Instead it wants a monotonic increasing value */
3888 get_monotonic_boottime(&ts);
3889 mgmt->u.probe_resp.timestamp =
3890 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3891#else
3892 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3894 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003895
3896#endif
3897
Jeff Johnson295189b2012-06-20 16:38:30 -07003898 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3899 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003900
3901#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3902 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3903 /* Assuming this is the last IE, copy at the end */
3904 ie_length -=sizeof(qcom_ie_age);
3905 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3906 qie_age->element_id = QCOM_VENDOR_IE_ID;
3907 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3908 qie_age->oui_1 = QCOM_OUI1;
3909 qie_age->oui_2 = QCOM_OUI2;
3910 qie_age->oui_3 = QCOM_OUI3;
3911 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3912 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3913#endif
3914
Jeff Johnson295189b2012-06-20 16:38:30 -07003915 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303916 if (bss_desc->fProbeRsp)
3917 {
3918 mgmt->frame_control |=
3919 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3920 }
3921 else
3922 {
3923 mgmt->frame_control |=
3924 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003926
3927#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303928 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3930 {
3931 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3932 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303933 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003934 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3935
3936 {
3937 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3938 }
3939 else
3940 {
3941 kfree(mgmt);
3942 return NULL;
3943 }
3944#else
3945 freq = ieee80211_channel_to_frequency(chan_no);
3946#endif
3947 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003948 /*when the band is changed on the fly using the GUI, three things are done
3949 * 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)
3950 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3951 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3952 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3953 * and discards the channels correponding to previous band and calls back with zero bss results.
3954 * 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
3955 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3956 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3957 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3958 * So drop the bss and continue to next bss.
3959 */
3960 if(chan == NULL)
3961 {
3962 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003963 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003964 return NULL;
3965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303967 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 * */
3969 if (( eConnectionState_Associated ==
3970 pAdapter->sessionCtx.station.conn_info.connState ) &&
3971 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3972 pAdapter->sessionCtx.station.conn_info.bssId,
3973 WNI_CFG_BSSID_LEN)))
3974 {
3975 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3976 rssi = (pAdapter->rssi * 100);
3977 }
3978 else
3979 {
3980 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3981 }
3982
3983 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3984 frame_len, rssi, GFP_KERNEL);
3985 kfree(mgmt);
3986 return bss_status;
3987}
3988
3989/*
3990 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3991 * This function is used to update the BSS data base of CFG8011
3992 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303993struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003994 tCsrRoamInfo *pRoamInfo
3995 )
3996{
3997 tCsrRoamConnectedProfile roamProfile;
3998 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3999 struct cfg80211_bss *bss = NULL;
4000
4001 ENTER();
4002
4003 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4004 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4005
4006 if (NULL != roamProfile.pBssDesc)
4007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304008 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004009 &roamProfile);
4010
4011 if (NULL == bss)
4012 {
4013 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4014 __func__);
4015 }
4016
4017 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4018 }
4019 else
4020 {
4021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4022 __func__);
4023 }
4024 return bss;
4025}
4026
4027/*
4028 * FUNCTION: wlan_hdd_cfg80211_update_bss
4029 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304030static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4031 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004032 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304033{
Jeff Johnson295189b2012-06-20 16:38:30 -07004034 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4035 tCsrScanResultInfo *pScanResult;
4036 eHalStatus status = 0;
4037 tScanResultHandle pResult;
4038 struct cfg80211_bss *bss_status = NULL;
4039
4040 ENTER();
4041
4042 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4043 {
4044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4045 return -EAGAIN;
4046 }
4047
4048 /*
4049 * start getting scan results and populate cgf80211 BSS database
4050 */
4051 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4052
4053 /* no scan results */
4054 if (NULL == pResult)
4055 {
4056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4057 return status;
4058 }
4059
4060 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4061
4062 while (pScanResult)
4063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 /*
4065 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4066 * entry already exists in bss data base of cfg80211 for that
4067 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4068 * bss entry instead of cfg80211_inform_bss, But this call expects
4069 * mgmt packet as input. As of now there is no possibility to get
4070 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004071 * ieee80211_mgmt(probe response) and passing to c
4072 * fg80211_inform_bss_frame.
4073 * */
4074
4075 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4076 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304077
Jeff Johnson295189b2012-06-20 16:38:30 -07004078
4079 if (NULL == bss_status)
4080 {
4081 hddLog(VOS_TRACE_LEVEL_INFO,
4082 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4083 }
4084 else
4085 {
4086 cfg80211_put_bss(bss_status);
4087 }
4088
4089 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4090 }
4091
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004093
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304094 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004095}
4096
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004097void
4098hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4099{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304100 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004101 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4102 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4103 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004104} /****** end hddPrintMacAddr() ******/
4105
4106void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004107hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304109 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004110 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4111 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4112 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4113 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004114} /****** end hddPrintPmkId() ******/
4115
4116//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4117//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4118
4119//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4120//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4121
4122#define dump_bssid(bssid) \
4123 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004124 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4125 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4126 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004127 }
4128
4129#define dump_pmkid(pMac, pmkid) \
4130 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004131 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4132 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4133 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004134 }
4135
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004136#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004137/*
4138 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4139 * This function is used to notify the supplicant of a new PMKSA candidate.
4140 */
4141int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304142 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143 int index, bool preauth )
4144{
Jeff Johnsone7245742012-09-05 17:12:55 -07004145#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004146 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004147 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004148
4149 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151
4152 if( NULL == pRoamInfo )
4153 {
4154 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4155 return -EINVAL;
4156 }
4157
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004158 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4159 {
4160 dump_bssid(pRoamInfo->bssid);
4161 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004162 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004163 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004164#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304165 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004166}
4167#endif //FEATURE_WLAN_LFR
4168
Jeff Johnson295189b2012-06-20 16:38:30 -07004169/*
4170 * FUNCTION: hdd_cfg80211_scan_done_callback
4171 * scanning callback function, called after finishing scan
4172 *
4173 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304174static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4176{
4177 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004180 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4181 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 struct cfg80211_scan_request *req = NULL;
4183 int ret = 0;
4184
4185 ENTER();
4186
4187 hddLog(VOS_TRACE_LEVEL_INFO,
4188 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304189 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004190 __func__, halHandle, pContext, (int) scanId, (int) status);
4191
4192 //Block on scan req completion variable. Can't wait forever though.
4193 ret = wait_for_completion_interruptible_timeout(
4194 &pScanInfo->scan_req_completion_event,
4195 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4196 if (!ret)
4197 {
4198 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004199 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004200 }
4201
4202 if(pScanInfo->mScanPending != VOS_TRUE)
4203 {
4204 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004205 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 }
4207
4208 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304209 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 {
4211 hddLog(VOS_TRACE_LEVEL_INFO,
4212 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004214 (int) scanId);
4215 }
4216
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304217 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 pAdapter);
4219
4220 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004222
4223
4224 /* If any client wait scan result through WEXT
4225 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004226 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 {
4228 /* The other scan request waiting for current scan finish
4229 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004230 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004232 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 }
4234 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004235 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004236 {
4237 struct net_device *dev = pAdapter->dev;
4238 union iwreq_data wrqu;
4239 int we_event;
4240 char *msg;
4241
4242 memset(&wrqu, '\0', sizeof(wrqu));
4243 we_event = SIOCGIWSCAN;
4244 msg = NULL;
4245 wireless_send_event(dev, we_event, &wrqu, msg);
4246 }
4247 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004248 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004249
4250 /* Get the Scan Req */
4251 req = pAdapter->request;
4252
4253 if (!req)
4254 {
4255 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004256 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004257 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 }
4259
4260 /*
4261 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304262 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 req->n_ssids = 0;
4264 req->n_channels = 0;
4265 req->ie = 0;
4266
Jeff Johnson295189b2012-06-20 16:38:30 -07004267 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004268 /* Scan is no longer pending */
4269 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004270
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004271 /*
4272 * cfg80211_scan_done informing NL80211 about completion
4273 * of scanning
4274 */
4275 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004276 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004277
Jeff Johnsone7245742012-09-05 17:12:55 -07004278allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004279 /* release the wake lock at the end of the scan*/
4280 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004281
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004282 /* Acquire wakelock to handle the case where APP's tries to suspend
4283 * immediatly after the driver gets connect request(i.e after scan)
4284 * from supplicant, this result in app's is suspending and not able
4285 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004286 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004287
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004288#ifdef FEATURE_WLAN_TDLS
4289 wlan_hdd_tdls_scan_done_callback(pAdapter);
4290#endif
4291
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 EXIT();
4293 return 0;
4294}
4295
4296/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004297 * FUNCTION: hdd_isScanAllowed
4298 * Go through each adapter and check if scan allowed
4299 *
4300 */
4301v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4302{
4303 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4304 hdd_station_ctx_t *pHddStaCtx = NULL;
4305 hdd_adapter_t *pAdapter = NULL;
4306 VOS_STATUS status = 0;
4307 v_U8_t staId = 0;
4308 v_U8_t *staMac = NULL;
4309
4310 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4311
4312 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4313 {
4314 pAdapter = pAdapterNode->pAdapter;
4315
4316 if( pAdapter )
4317 {
4318 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304319 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004320 __func__, pAdapter->device_mode);
4321 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4322 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4323 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4324 {
4325 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4326 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4327 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4328 {
4329 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4330 hddLog(VOS_TRACE_LEVEL_ERROR,
4331 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304332 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004333 staMac[0], staMac[1], staMac[2],
4334 staMac[3], staMac[4], staMac[5]);
4335 return VOS_FALSE;
4336 }
4337 }
4338 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4339 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4340 {
4341 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304343 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004344 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4345 {
4346 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4347
4348 hddLog(VOS_TRACE_LEVEL_ERROR,
4349 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304350 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004351 staMac[0], staMac[1], staMac[2],
4352 staMac[3], staMac[4], staMac[5]);
4353 return VOS_FALSE;
4354 }
4355 }
4356 }
4357 }
4358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4359 pAdapterNode = pNext;
4360 }
4361 hddLog(VOS_TRACE_LEVEL_INFO,
4362 "%s: Scan allowed", __func__);
4363 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304364}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004365
4366/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004367 * FUNCTION: wlan_hdd_cfg80211_scan
4368 * this scan respond to scan trigger and update cfg80211 scan database
4369 * later, scan dump command can be used to recieve scan results
4370 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004371int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4372#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4373 struct net_device *dev,
4374#endif
4375 struct cfg80211_scan_request *request)
4376{
4377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4378 struct net_device *dev = request->wdev->netdev;
4379#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4382 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304383 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 tCsrScanRequest scanRequest;
4385 tANI_U8 *channelList = NULL, i;
4386 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304387 int status;
4388 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004389 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004390
4391 ENTER();
4392
4393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4394 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004395
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304396 status = wlan_hdd_validate_context(pHddCtx);
4397
4398 if (0 != status)
4399 {
4400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4401 "%s: HDD context is not valid", __func__);
4402 return status;
4403 }
4404
4405 cfg_param = pHddCtx->cfg_ini;
4406 pScanInfo = &pHddCtx->scan_info;
4407
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004408 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004409 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004410 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004411 {
4412 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004413 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4414 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004415 return -EBUSY;
4416 }
4417
Jeff Johnson295189b2012-06-20 16:38:30 -07004418#ifdef WLAN_BTAMP_FEATURE
4419 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 "%s: No scanning when AMP is on", __func__);
4424 return -EOPNOTSUPP;
4425 }
4426#endif
4427 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004428 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004429 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004430 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004431 "%s: Not scanning on device_mode = %d",
4432 __func__, pAdapter->device_mode);
4433 return -EOPNOTSUPP;
4434 }
4435
4436 if (TRUE == pScanInfo->mScanPending)
4437 {
4438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004439 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004440 }
4441
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304442 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004443 //Channel and action frame is pending
4444 //Otherwise Cancel Remain On Channel and allow Scan
4445 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004446 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004447 {
4448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4449 return -EBUSY;
4450 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004451#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004452 /* if tdls disagree scan right now, return immediately.
4453 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4454 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4455 */
4456 status = wlan_hdd_tdls_scan_callback (pAdapter,
4457 wiphy,
4458#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4459 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004460#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004461 request);
4462 if(status <= 0)
4463 {
4464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4465 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004466 }
4467#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004468
Jeff Johnson295189b2012-06-20 16:38:30 -07004469 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4470 {
4471 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004472 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004473 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004475 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4476 {
4477 hddLog(VOS_TRACE_LEVEL_WARN,
4478 "%s: MAX TM Level Scan not allowed", __func__);
4479 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304480 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004481 }
4482 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4483
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004484 /* Check if scan is allowed at this point of time.
4485 */
4486 if (!hdd_isScanAllowed(pHddCtx))
4487 {
4488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4489 return -EBUSY;
4490 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304491
Jeff Johnson295189b2012-06-20 16:38:30 -07004492 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4493
4494 if (NULL != request)
4495 {
4496 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304497 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004498
4499 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4500 * Becasue of this, driver is assuming that this is not wildcard scan and so
4501 * is not aging out the scan results.
4502 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004503 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 {
4505 request->n_ssids = 0;
4506 }
4507
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004508 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004509 {
4510 tCsrSSIDInfo *SsidInfo;
4511 int j;
4512 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4513 /* Allocate num_ssid tCsrSSIDInfo structure */
4514 SsidInfo = scanRequest.SSIDs.SSIDList =
4515 ( tCsrSSIDInfo *)vos_mem_malloc(
4516 request->n_ssids*sizeof(tCsrSSIDInfo));
4517
4518 if(NULL == scanRequest.SSIDs.SSIDList)
4519 {
4520 hddLog(VOS_TRACE_LEVEL_ERROR,
4521 "memory alloc failed SSIDInfo buffer");
4522 return -ENOMEM;
4523 }
4524
4525 /* copy all the ssid's and their length */
4526 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4527 {
4528 /* get the ssid length */
4529 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4530 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4531 SsidInfo->SSID.length);
4532 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4533 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4534 j, SsidInfo->SSID.ssId);
4535 }
4536 /* set the scan type to active */
4537 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4538 }
4539 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4540 {
4541 /* set the scan type to active */
4542 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4543 }
4544 else
4545 {
4546 /*Set the scan type to default type, in this case it is ACTIVE*/
4547 scanRequest.scanType = pScanInfo->scan_mode;
4548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304549 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004550 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4551 }
4552 else
4553 {
4554 /* set the scan type to active */
4555 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4556 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4557
4558 /* set min and max channel time to zero */
4559 scanRequest.minChnTime = 0;
4560 scanRequest.maxChnTime = 0;
4561 }
4562
4563 /* set BSSType to default type */
4564 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4565
4566 /*TODO: scan the requested channels only*/
4567
4568 /*Right now scanning all the channels */
4569 if( request )
4570 {
4571 if( request->n_channels )
4572 {
4573 channelList = vos_mem_malloc( request->n_channels );
4574 if( NULL == channelList )
4575 {
4576 status = -ENOMEM;
4577 goto free_mem;
4578 }
4579
4580 for( i = 0 ; i < request->n_channels ; i++ )
4581 channelList[i] = request->channels[i]->hw_value;
4582 }
4583
4584 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4585 scanRequest.ChannelInfo.ChannelList = channelList;
4586
4587 /* set requestType to full scan */
4588 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304589
4590 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004591 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304592 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004593 */
4594
4595 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304596 * and in that case driver shoudnt flush scan results. If
4597 * driver flushes the scan results here and unfortunately if
4598 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004599 * fails which is not desired
4600 */
4601
4602 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4603 {
4604 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4605 pAdapter->sessionId );
4606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004607
4608 if( request->ie_len )
4609 {
4610 /* save this for future association (join requires this) */
4611 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4612 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4613 pScanInfo->scanAddIE.length = request->ie_len;
4614
4615 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004616 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4617 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004618 )
4619 {
4620 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4621 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4622 }
4623
4624 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4625 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4626
Jeff Johnson295189b2012-06-20 16:38:30 -07004627 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4628 request->ie_len);
4629 if (pP2pIe != NULL)
4630 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004631#ifdef WLAN_FEATURE_P2P_DEBUG
4632 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4633 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4634 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4635 {
4636 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4637 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4638 "Go nego completed to Connection is started");
4639 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4640 "for 8way Handshake");
4641 }
4642 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4643 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4644 {
4645 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4646 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4647 "Disconnected state to Connection is started");
4648 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4649 "for 4way Handshake");
4650 }
4651#endif
4652
Jeff Johnsone7245742012-09-05 17:12:55 -07004653 /* no_cck will be set during p2p find to disable 11b rates */
4654 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004656 hddLog(VOS_TRACE_LEVEL_INFO,
4657 "%s: This is a P2P Search", __func__);
4658 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004659
Jeff Johnsone7245742012-09-05 17:12:55 -07004660 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4661 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004662 /* set requestType to P2P Discovery */
4663 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004664 }
4665
4666 /*
4667 Skip Dfs Channel in case of P2P Search
4668 if it is set in ini file
4669 */
4670 if(cfg_param->skipDfsChnlInP2pSearch)
4671 {
4672 scanRequest.skipDfsChnlInP2pSearch = 1;
4673 }
4674 else
4675 {
4676 scanRequest.skipDfsChnlInP2pSearch = 0;
4677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004678
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 }
4680 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 }
4682 }
4683
4684 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4685
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004686 /* acquire the wakelock to avoid the apps suspend during the scan. To
4687 * address the following issues.
4688 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4689 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4690 * for long time, this result in apps running at full power for long time.
4691 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4692 * be stuck in full power because of resume BMPS
4693 */
4694 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004695
4696 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004697 pAdapter->sessionId, &scanRequest, &scanId,
4698 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004699
Jeff Johnson295189b2012-06-20 16:38:30 -07004700 if (eHAL_STATUS_SUCCESS != status)
4701 {
4702 hddLog(VOS_TRACE_LEVEL_ERROR,
4703 "%s: sme_ScanRequest returned error %d", __func__, status);
4704 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004705 if(eHAL_STATUS_RESOURCES == status)
4706 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004707 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 -07004708 status = -EBUSY;
4709 } else {
4710 status = -EIO;
4711 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004712 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004713 goto free_mem;
4714 }
4715
4716 pScanInfo->mScanPending = TRUE;
4717 pAdapter->request = request;
4718 pScanInfo->scanId = scanId;
4719
4720 complete(&pScanInfo->scan_req_completion_event);
4721
4722free_mem:
4723 if( scanRequest.SSIDs.SSIDList )
4724 {
4725 vos_mem_free(scanRequest.SSIDs.SSIDList);
4726 }
4727
4728 if( channelList )
4729 vos_mem_free( channelList );
4730
4731 EXIT();
4732
4733 return status;
4734}
4735
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004736
4737void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4738{
4739 v_U8_t iniDot11Mode =
4740 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4741 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4742
4743 switch ( iniDot11Mode )
4744 {
4745 case eHDD_DOT11_MODE_AUTO:
4746 case eHDD_DOT11_MODE_11ac:
4747 case eHDD_DOT11_MODE_11ac_ONLY:
4748#ifdef WLAN_FEATURE_11AC
4749 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4750#else
4751 hddDot11Mode = eHDD_DOT11_MODE_11n;
4752#endif
4753 break;
4754 case eHDD_DOT11_MODE_11n:
4755 case eHDD_DOT11_MODE_11n_ONLY:
4756 hddDot11Mode = eHDD_DOT11_MODE_11n;
4757 break;
4758 default:
4759 hddDot11Mode = iniDot11Mode;
4760 break;
4761 }
4762 /* This call decides required channel bonding mode */
4763 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4764 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4765 operationChannel);
4766}
4767
Jeff Johnson295189b2012-06-20 16:38:30 -07004768/*
4769 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304770 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004771 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304772int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004773 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004774{
4775 int status = 0;
4776 hdd_wext_state_t *pWextState;
4777 v_U32_t roamId;
4778 tCsrRoamProfile *pRoamProfile;
4779 eMib_dot11DesiredBssType connectedBssType;
4780 eCsrAuthType RSNAuthType;
4781
4782 ENTER();
4783
4784 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304785
Jeff Johnson295189b2012-06-20 16:38:30 -07004786 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4787 {
4788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4789 return -EINVAL;
4790 }
4791
4792 pRoamProfile = &pWextState->roamProfile;
4793
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304794 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004795 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004796 int ret = 0;
4797 hdd_station_ctx_t *pHddStaCtx;
4798 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4799 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4800
4801 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4802 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4803 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004804 {
4805 /* Issue disconnect to CSR */
4806 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304807 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004808 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4809 pAdapter->sessionId,
4810 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4811 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004812 ret = wait_for_completion_interruptible_timeout(
4813 &pAdapter->disconnect_comp_var,
4814 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4815 if (0 == ret)
4816 {
4817 VOS_ASSERT(0);
4818 }
4819 }
4820 }
4821 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4822 {
4823 ret = wait_for_completion_interruptible_timeout(
4824 &pAdapter->disconnect_comp_var,
4825 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4826 if (0 == ret)
4827 {
4828 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004829 }
4830 }
4831
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304832 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004833 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4834 {
4835 /*QoS not enabled in cfg file*/
4836 pRoamProfile->uapsd_mask = 0;
4837 }
4838 else
4839 {
4840 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304841 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004842 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4843 }
4844
4845 pRoamProfile->SSIDs.numOfSSIDs = 1;
4846 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4847 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304848 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004849 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4850 ssid, ssid_len);
4851
4852 if (bssid)
4853 {
4854 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4855 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4856 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304857 /* Save BSSID in seperate variable as well, as RoamProfile
4858 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 case of join failure we should send valid BSSID to supplicant
4860 */
4861 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4862 WNI_CFG_BSSID_LEN);
4863 }
4864
4865 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4866 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304867 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004868 /*set gen ie*/
4869 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4870 /*set auth*/
4871 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004873#ifdef FEATURE_WLAN_WAPI
4874 if (pAdapter->wapi_info.nWapiMode)
4875 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004876 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004877 switch (pAdapter->wapi_info.wapiAuthMode)
4878 {
4879 case WAPI_AUTH_MODE_PSK:
4880 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004881 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 pAdapter->wapi_info.wapiAuthMode);
4883 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4884 break;
4885 }
4886 case WAPI_AUTH_MODE_CERT:
4887 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004888 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004889 pAdapter->wapi_info.wapiAuthMode);
4890 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4891 break;
4892 }
4893 } // End of switch
4894 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4895 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4896 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004897 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004898 pRoamProfile->AuthType.numEntries = 1;
4899 pRoamProfile->EncryptionType.numEntries = 1;
4900 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4901 pRoamProfile->mcEncryptionType.numEntries = 1;
4902 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4903 }
4904 }
4905#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304906#ifdef WLAN_FEATURE_GTK_OFFLOAD
4907 /* Initializing gtkOffloadRequestParams */
4908 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4909 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4910 {
4911 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4912 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4913 0, sizeof (tSirGtkOffloadParams));
4914 }
4915#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 pRoamProfile->csrPersona = pAdapter->device_mode;
4917
Jeff Johnson32d95a32012-09-10 13:15:23 -07004918 if( operatingChannel )
4919 {
4920 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4921 pRoamProfile->ChannelInfo.numOfChannels = 1;
4922 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004923 else
4924 {
4925 pRoamProfile->ChannelInfo.ChannelList = NULL;
4926 pRoamProfile->ChannelInfo.numOfChannels = 0;
4927 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004928 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4929 {
4930 hdd_select_cbmode(pAdapter,operatingChannel);
4931 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004932 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4933 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304934 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004935 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004936 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4937 */
4938 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4939 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4940 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304941
4942 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 pAdapter->sessionId, pRoamProfile, &roamId);
4944
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004945 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304946 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4947
4948 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4950 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4951 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304952 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004953 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304954 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004955
4956 pRoamProfile->ChannelInfo.ChannelList = NULL;
4957 pRoamProfile->ChannelInfo.numOfChannels = 0;
4958
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 }
4960 else
4961 {
4962 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4963 return -EINVAL;
4964 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004965 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004966 return status;
4967}
4968
4969/*
4970 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4971 * This function is used to set the authentication type (OPEN/SHARED).
4972 *
4973 */
4974static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4975 enum nl80211_auth_type auth_type)
4976{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304977 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004978 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4979
4980 ENTER();
4981
4982 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304983 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004984 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304986 hddLog(VOS_TRACE_LEVEL_INFO,
4987 "%s: set authentication type to AUTOSWITCH", __func__);
4988 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4989 break;
4990
4991 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004992#ifdef WLAN_FEATURE_VOWIFI_11R
4993 case NL80211_AUTHTYPE_FT:
4994#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304995 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 "%s: set authentication type to OPEN", __func__);
4997 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4998 break;
4999
5000 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305001 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005002 "%s: set authentication type to SHARED", __func__);
5003 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5004 break;
5005#ifdef FEATURE_WLAN_CCX
5006 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005008 "%s: set authentication type to CCKM WPA", __func__);
5009 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5010 break;
5011#endif
5012
5013
5014 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305015 hddLog(VOS_TRACE_LEVEL_ERROR,
5016 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 auth_type);
5018 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5019 return -EINVAL;
5020 }
5021
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305022 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 pHddStaCtx->conn_info.authType;
5024 return 0;
5025}
5026
5027/*
5028 * FUNCTION: wlan_hdd_set_akm_suite
5029 * This function is used to set the key mgmt type(PSK/8021x).
5030 *
5031 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305032static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005033 u32 key_mgmt
5034 )
5035{
5036 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5037 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305038
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 /*set key mgmt type*/
5040 switch(key_mgmt)
5041 {
5042 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305043#ifdef WLAN_FEATURE_VOWIFI_11R
5044 case WLAN_AKM_SUITE_FT_PSK:
5045#endif
5046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 __func__);
5048 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5049 break;
5050
5051 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305052#ifdef WLAN_FEATURE_VOWIFI_11R
5053 case WLAN_AKM_SUITE_FT_8021X:
5054#endif
5055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 __func__);
5057 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5058 break;
5059#ifdef FEATURE_WLAN_CCX
5060#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5061#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5062 case WLAN_AKM_SUITE_CCKM:
5063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5064 __func__);
5065 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5066 break;
5067#endif
5068
5069 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 __func__, key_mgmt);
5072 return -EINVAL;
5073
5074 }
5075 return 0;
5076}
5077
5078/*
5079 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305080 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 * (NONE/WEP40/WEP104/TKIP/CCMP).
5082 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5084 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 bool ucast
5086 )
5087{
5088 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305089 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5091
5092 ENTER();
5093
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 __func__, cipher);
5098 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5099 }
5100 else
5101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305102
Jeff Johnson295189b2012-06-20 16:38:30 -07005103 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305104 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 {
5106 case IW_AUTH_CIPHER_NONE:
5107 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5108 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305111 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305115 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305117
Jeff Johnson295189b2012-06-20 16:38:30 -07005118 case WLAN_CIPHER_SUITE_TKIP:
5119 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5120 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305121
Jeff Johnson295189b2012-06-20 16:38:30 -07005122 case WLAN_CIPHER_SUITE_CCMP:
5123 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5124 break;
5125#ifdef FEATURE_WLAN_WAPI
5126 case WLAN_CIPHER_SUITE_SMS4:
5127 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5128 break;
5129#endif
5130
5131#ifdef FEATURE_WLAN_CCX
5132 case WLAN_CIPHER_SUITE_KRK:
5133 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5134 break;
5135#endif
5136 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 __func__, cipher);
5139 return -EOPNOTSUPP;
5140 }
5141 }
5142
5143 if (ucast)
5144 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305145 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 __func__, encryptionType);
5147 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5148 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305149 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 encryptionType;
5151 }
5152 else
5153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305154 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005155 __func__, encryptionType);
5156 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5157 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5158 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5159 }
5160
5161 return 0;
5162}
5163
5164
5165/*
5166 * FUNCTION: wlan_hdd_cfg80211_set_ie
5167 * This function is used to parse WPA/RSN IE's.
5168 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5170 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005171 size_t ie_len
5172 )
5173{
5174 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5175 u8 *genie = ie;
5176 v_U16_t remLen = ie_len;
5177#ifdef FEATURE_WLAN_WAPI
5178 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5179 u16 *tmp;
5180 v_U16_t akmsuiteCount;
5181 int *akmlist;
5182#endif
5183 ENTER();
5184
5185 /* clear previous assocAddIE */
5186 pWextState->assocAddIE.length = 0;
5187 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5188
5189 while (remLen >= 2)
5190 {
5191 v_U16_t eLen = 0;
5192 v_U8_t elementId;
5193 elementId = *genie++;
5194 eLen = *genie++;
5195 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305196
5197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305199
5200 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305202 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005203 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 -07005204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305205 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 "%s: Invalid WPA IE", __func__);
5207 return -EINVAL;
5208 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305209 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 {
5211 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305212 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305214
Jeff Johnson295189b2012-06-20 16:38:30 -07005215 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5216 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005217 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5218 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 VOS_ASSERT(0);
5220 return -ENOMEM;
5221 }
5222 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5223 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5224 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305225
Jeff Johnson295189b2012-06-20 16:38:30 -07005226 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5227 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5228 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5229 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305230 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5231 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5233 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5234 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5235 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5236 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5237 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305238 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5239 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 /*Consider P2P IE, only for P2P Client */
5241 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5242 {
5243 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305246
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5248 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005249 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5250 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 VOS_ASSERT(0);
5252 return -ENOMEM;
5253 }
5254 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5255 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5256 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305257
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5259 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5260 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005261#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5263 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 /*Consider WFD IE, only for P2P Client */
5265 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5266 {
5267 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305268 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005269 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305270
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5272 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005273 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5274 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 VOS_ASSERT(0);
5276 return -ENOMEM;
5277 }
5278 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5279 // WPS IE + P2P IE + WFD IE
5280 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5281 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305282
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5284 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5285 }
5286#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005287 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305288 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005289 HS20_OUI_TYPE_SIZE)) )
5290 {
5291 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305292 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005293 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005294
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005295 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5296 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005297 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5298 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005299 VOS_ASSERT(0);
5300 return -ENOMEM;
5301 }
5302 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5303 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005304
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005305 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5306 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5307 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005308
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 break;
5310 case DOT11F_EID_RSN:
5311 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5312 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5313 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5314 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5315 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5316 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005317 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5318 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305319 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005320 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305321 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005322 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305323
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005324 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5325 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005326 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5327 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005328 VOS_ASSERT(0);
5329 return -ENOMEM;
5330 }
5331 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5332 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305333
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005334 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5335 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5336 break;
5337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005338#ifdef FEATURE_WLAN_WAPI
5339 case WLAN_EID_WAPI:
5340 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5341 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5342 pAdapter->wapi_info.nWapiMode);
5343 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305344 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 akmsuiteCount = WPA_GET_LE16(tmp);
5346 tmp = tmp + 1;
5347 akmlist = (int *)(tmp);
5348 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5349 {
5350 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5351 }
5352 else
5353 {
5354 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5355 VOS_ASSERT(0);
5356 return -EINVAL;
5357 }
5358
5359 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5360 {
5361 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005362 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005363 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305366 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005368 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5370 }
5371 break;
5372#endif
5373 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305374 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005376 /* when Unknown IE is received we should break and continue
5377 * to the next IE in the buffer instead we were returning
5378 * so changing this to break */
5379 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 }
5381 genie += eLen;
5382 remLen -= eLen;
5383 }
5384 EXIT();
5385 return 0;
5386}
5387
5388/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305389 * FUNCTION: hdd_isWPAIEPresent
5390 * Parse the received IE to find the WPA IE
5391 *
5392 */
5393static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5394{
5395 v_U8_t eLen = 0;
5396 v_U16_t remLen = ie_len;
5397 v_U8_t elementId = 0;
5398
5399 while (remLen >= 2)
5400 {
5401 elementId = *ie++;
5402 eLen = *ie++;
5403 remLen -= 2;
5404 if (eLen > remLen)
5405 {
5406 hddLog(VOS_TRACE_LEVEL_ERROR,
5407 "%s: IE length is wrong %d", __func__, eLen);
5408 return FALSE;
5409 }
5410 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5411 {
5412 /* OUI - 0x00 0X50 0XF2
5413 WPA Information Element - 0x01
5414 WPA version - 0x01*/
5415 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5416 return TRUE;
5417 }
5418 ie += eLen;
5419 remLen -= eLen;
5420 }
5421 return FALSE;
5422}
5423
5424/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 * parameters during connect operation.
5428 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305429int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 struct cfg80211_connect_params *req
5431 )
5432{
5433 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305434 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 ENTER();
5436
5437 /*set wpa version*/
5438 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 {
5442 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305443 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305444 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305446 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005447 * since p2p ie is also put in same buffer.
5448 * */
5449 {
5450 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5451 }
5452 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5453 {
5454 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5455 }
5456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305457
5458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 pWextState->wpaVersion);
5460
5461 /*set authentication type*/
5462 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5463
5464 if (0 > status)
5465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305466 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 "%s: failed to set authentication type ", __func__);
5468 return status;
5469 }
5470
5471 /*set key mgmt type*/
5472 if (req->crypto.n_akm_suites)
5473 {
5474 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5475 if (0 > status)
5476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 __func__);
5479 return status;
5480 }
5481 }
5482
5483 /*set pairwise cipher type*/
5484 if (req->crypto.n_ciphers_pairwise)
5485 {
5486 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5487 req->crypto.ciphers_pairwise[0], true);
5488 if (0 > status)
5489 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305490 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 "%s: failed to set unicast cipher type", __func__);
5492 return status;
5493 }
5494 }
5495 else
5496 {
5497 /*Reset previous cipher suite to none*/
5498 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5499 if (0 > status)
5500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305501 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 "%s: failed to set unicast cipher type", __func__);
5503 return status;
5504 }
5505 }
5506
5507 /*set group cipher type*/
5508 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5509 false);
5510
5511 if (0 > status)
5512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 __func__);
5515 return status;
5516 }
5517
Chet Lanctot186b5732013-03-18 10:26:30 -07005518#ifdef WLAN_FEATURE_11W
5519 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5520#endif
5521
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5523 if (req->ie_len)
5524 {
5525 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5526 if ( 0 > status)
5527 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 __func__);
5530 return status;
5531 }
5532 }
5533
5534 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305535 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 {
5537 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5538 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5539 )
5540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305541 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 __func__);
5546 return -EOPNOTSUPP;
5547 }
5548 else
5549 {
5550 u8 key_len = req->key_len;
5551 u8 key_idx = req->key_idx;
5552
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 && (CSR_MAX_NUM_KEY > key_idx)
5555 )
5556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 hddLog(VOS_TRACE_LEVEL_INFO,
5558 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005559 __func__, key_idx, key_len);
5560 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305561 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305563 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005564 (u8)key_len;
5565 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5566 }
5567 }
5568 }
5569 }
5570
5571 return status;
5572}
5573
5574/*
5575 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305576 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 * parameters during connect operation.
5578 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305579static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 struct net_device *ndev,
5581 struct cfg80211_connect_params *req
5582 )
5583{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305584 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305585 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5587 hdd_context_t *pHddCtx = NULL;
5588
5589 ENTER();
5590
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305591 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5593
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305594 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5595 status = wlan_hdd_validate_context(pHddCtx);
5596
5597 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5600 "%s: HDD context is not valid", __func__);
5601 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 }
5603
5604#ifdef WLAN_BTAMP_FEATURE
5605 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305606 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005610 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 }
5612#endif
5613 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305614 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005615
5616 if ( 0 > status)
5617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 __func__);
5620 return status;
5621 }
5622
5623 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005624 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5626 (vos_concurrent_sessions_running()))
5627 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305628 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 }
5630
Mohit Khanna765234a2012-09-11 15:08:35 -07005631 if ( req->channel )
5632 {
5633 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5634 req->ssid_len, req->bssid,
5635 req->channel->hw_value);
5636 }
5637 else
5638 {
5639 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305640 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005642
5643 if (0 > status)
5644 {
5645 //ReEnable BMPS if disabled
5646 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5647 (NULL != pHddCtx))
5648 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305649 if (pHddCtx->hdd_wlan_suspended)
5650 {
5651 hdd_set_pwrparams(pHddCtx);
5652 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 //ReEnable Bmps and Imps back
5654 hdd_enable_bmps_imps(pHddCtx);
5655 }
5656
5657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5658 return status;
5659 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305660 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005661 EXIT();
5662 return status;
5663}
5664
5665
5666/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305667 * FUNCTION: wlan_hdd_disconnect
5668 * This function is used to issue a disconnect request to SME
5669 */
5670int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5671{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305672 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305673 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305674 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5675
5676 status = wlan_hdd_validate_context(pHddCtx);
5677
5678 if (0 != status)
5679 {
5680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5681 "%s: HDD context is not valid", __func__);
5682 return status;
5683 }
5684
5685 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305686 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305687 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305688
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305689 /*issue disconnect*/
5690 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5691 pAdapter->sessionId, reason);
5692
5693 if ( 0 != status )
5694 {
5695 hddLog(VOS_TRACE_LEVEL_ERROR,
5696 "%s csrRoamDisconnect failure, returned %d \n",
5697 __func__, (int)status );
5698 return -EINVAL;
5699 }
5700 wait_for_completion_interruptible_timeout(
5701 &pAdapter->disconnect_comp_var,
5702 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5703 /*stop tx queues*/
5704 netif_tx_disable(pAdapter->dev);
5705 netif_carrier_off(pAdapter->dev);
5706 return status;
5707}
5708
5709
5710/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 * FUNCTION: wlan_hdd_cfg80211_disconnect
5712 * This function is used to issue a disconnect request to SME
5713 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305714static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005715 struct net_device *dev,
5716 u16 reason
5717 )
5718{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5720 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305722 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005724 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305725#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005726 tANI_U8 staIdx;
5727#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305728
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730
5731 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 __func__,pAdapter->device_mode);
5733
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5735 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005736
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305737 status = wlan_hdd_validate_context(pHddCtx);
5738
5739 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5742 "%s: HDD context is not valid", __func__);
5743 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305745
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 if (NULL != pRoamProfile)
5747 {
5748 /*issue disconnect request to SME, if station is in connected state*/
5749 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305753 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 switch(reason)
5755 {
5756 case WLAN_REASON_MIC_FAILURE:
5757 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5758 break;
5759
5760 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5761 case WLAN_REASON_DISASSOC_AP_BUSY:
5762 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5763 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5764 break;
5765
5766 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5767 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5768 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5769 break;
5770
5771 case WLAN_REASON_DEAUTH_LEAVING:
5772 default:
5773 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5774 break;
5775 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305776 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5777 pScanInfo = &pHddCtx->scan_info;
5778 if (pScanInfo->mScanPending)
5779 {
5780 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5781 "Aborting Scan");
5782 hdd_abort_mac_scan(pHddCtx);
5783 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005784
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005785#ifdef FEATURE_WLAN_TDLS
5786 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005787 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005788 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005789 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5790 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005791 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005792 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005793 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005794 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005795 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005796 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005797 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005798 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005799 pAdapter->sessionId,
5800 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005801 }
5802 }
5803#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305804 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5805 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 {
5807 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305808 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 __func__, (int)status );
5810 return -EINVAL;
5811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 }
5813 }
5814 else
5815 {
5816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5817 }
5818
5819 return status;
5820}
5821
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305822
Jeff Johnson295189b2012-06-20 16:38:30 -07005823/*
5824 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 * settings in IBSS mode.
5827 */
5828static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 struct cfg80211_ibss_params *params
5831 )
5832{
5833 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5836 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305837
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 ENTER();
5839
5840 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5841
5842 if (params->ie_len && ( NULL != params->ie) )
5843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305844 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 {
5846 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5847 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5848 }
5849 else
5850 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005851 tDot11fIEWPA dot11WPAIE;
5852 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5853
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005855 // Unpack the WPA IE
5856 //Skip past the EID byte and length byte - and four byte WiFi OUI
5857 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5858 &params->ie[2+4],
5859 params->ie[1] - 4,
5860 &dot11WPAIE);
5861 /*Extract the multicast cipher, the encType for unicast
5862 cipher for wpa-none is none*/
5863 encryptionType =
5864 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 }
5866 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5867
5868 if (0 > status)
5869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 __func__);
5872 return status;
5873 }
5874 }
5875
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305876 pWextState->roamProfile.AuthType.authType[0] =
5877 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5879
5880 if (params->privacy)
5881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305882 /* Security enabled IBSS, At this time there is no information available
5883 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 *enable privacy bit in beacons */
5889
5890 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5891 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005892 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5893 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5895 pWextState->roamProfile.EncryptionType.numEntries = 1;
5896 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 return status;
5898}
5899
5900/*
5901 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305902 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 struct net_device *dev,
5906 struct cfg80211_ibss_params *params
5907 )
5908{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5911 tCsrRoamProfile *pRoamProfile;
5912 int status;
5913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305914 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005915
5916 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305917
5918 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5920
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305921 status = wlan_hdd_validate_context(pHddCtx);
5922
5923 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5926 "%s: HDD context is not valid", __func__);
5927 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 }
5929
5930 if (NULL == pWextState)
5931 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 __func__);
5934 return -EIO;
5935 }
5936
5937 pRoamProfile = &pWextState->roamProfile;
5938
5939 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5940 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305941 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 "%s Interface type is not set to IBSS \n", __func__);
5943 return -EINVAL;
5944 }
5945
5946 /* Set Channel */
5947 if (NULL != params->channel)
5948 {
5949 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005950 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5951 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5952 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5953 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005954
5955 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 ieee80211_frequency_to_channel(params->channel->center_freq);
5958
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005959
5960 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5961 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5964 __func__);
5965 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005967
5968 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005970 if (channelNum == validChan[indx])
5971 {
5972 break;
5973 }
5974 }
5975 if (indx >= numChans)
5976 {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 __func__, channelNum);
5979 return -EINVAL;
5980 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005981 /* Set the Operational Channel */
5982 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5983 channelNum);
5984 pRoamProfile->ChannelInfo.numOfChannels = 1;
5985 pHddStaCtx->conn_info.operationChannel = channelNum;
5986 pRoamProfile->ChannelInfo.ChannelList =
5987 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 }
5989
5990 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305991 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 if (status < 0)
5993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 __func__);
5996 return status;
5997 }
5998
5999 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306000 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006001 params->ssid_len, params->bssid,
6002 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006003
6004 if (0 > status)
6005 {
6006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6007 return status;
6008 }
6009
6010 return 0;
6011}
6012
6013/*
6014 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306015 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 struct net_device *dev
6019 )
6020{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6023 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306024 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6025 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006026
6027 ENTER();
6028
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306029 status = wlan_hdd_validate_context(pHddCtx);
6030
6031 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6034 "%s: HDD context is not valid", __func__);
6035 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006036 }
6037
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6039 if (NULL == pWextState)
6040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 __func__);
6043 return -EIO;
6044 }
6045
6046 pRoamProfile = &pWextState->roamProfile;
6047
6048 /* Issue disconnect only if interface type is set to IBSS */
6049 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306051 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 __func__);
6053 return -EINVAL;
6054 }
6055
6056 /* Issue Disconnect request */
6057 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6058 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6059 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6060
6061 return 0;
6062}
6063
6064/*
6065 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6066 * This function is used to set the phy parameters
6067 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6068 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306069static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 u32 changed)
6071{
6072 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6073 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306074 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006075
6076 ENTER();
6077
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306078 status = wlan_hdd_validate_context(pHddCtx);
6079
6080 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6083 "%s: HDD context is not valid", __func__);
6084 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006085 }
6086
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6088 {
6089 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6090 WNI_CFG_RTS_THRESHOLD_STAMAX :
6091 wiphy->rts_threshold;
6092
6093 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306094 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 hddLog(VOS_TRACE_LEVEL_ERROR,
6097 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 __func__, rts_threshold);
6099 return -EINVAL;
6100 }
6101
6102 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6103 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306104 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 hddLog(VOS_TRACE_LEVEL_ERROR,
6107 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 __func__, rts_threshold);
6109 return -EIO;
6110 }
6111
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306112 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 rts_threshold);
6114 }
6115
6116 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6117 {
6118 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6119 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6120 wiphy->frag_threshold;
6121
6122 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 hddLog(VOS_TRACE_LEVEL_ERROR,
6126 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 frag_threshold);
6128 return -EINVAL;
6129 }
6130
6131 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6132 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306133 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306135 hddLog(VOS_TRACE_LEVEL_ERROR,
6136 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 __func__, frag_threshold);
6138 return -EIO;
6139 }
6140
6141 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6142 frag_threshold);
6143 }
6144
6145 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6146 || (changed & WIPHY_PARAM_RETRY_LONG))
6147 {
6148 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6149 wiphy->retry_short :
6150 wiphy->retry_long;
6151
6152 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6153 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6154 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 __func__, retry_value);
6157 return -EINVAL;
6158 }
6159
6160 if (changed & WIPHY_PARAM_RETRY_SHORT)
6161 {
6162 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6163 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306164 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306166 hddLog(VOS_TRACE_LEVEL_ERROR,
6167 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 __func__, retry_value);
6169 return -EIO;
6170 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 __func__, retry_value);
6173 }
6174 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6175 {
6176 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6177 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306178 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006179 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306180 hddLog(VOS_TRACE_LEVEL_ERROR,
6181 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 __func__, retry_value);
6183 return -EIO;
6184 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306185 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 __func__, retry_value);
6187 }
6188 }
6189
6190 return 0;
6191}
6192
6193/*
6194 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6195 * This function is used to set the txpower
6196 */
6197static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6198#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306199 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006200#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306201 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006202#endif
6203 int dbm)
6204{
6205 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306206 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6208 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306209 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006210
6211 ENTER();
6212
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306213 status = wlan_hdd_validate_context(pHddCtx);
6214
6215 if (0 != status)
6216 {
6217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6218 "%s: HDD context is not valid", __func__);
6219 return status;
6220 }
6221
6222 hHal = pHddCtx->hHal;
6223
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306224 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6225 dbm, ccmCfgSetCallback,
6226 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306228 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6230 return -EIO;
6231 }
6232
6233 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6234 dbm);
6235
6236 switch(type)
6237 {
6238 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6239 /* Fall through */
6240 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6241 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6242 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6244 __func__);
6245 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 }
6247 break;
6248 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 __func__);
6251 return -EOPNOTSUPP;
6252 break;
6253 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6255 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 return -EIO;
6257 }
6258
6259 return 0;
6260}
6261
6262/*
6263 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6264 * This function is used to read the txpower
6265 */
6266static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6267{
6268
6269 hdd_adapter_t *pAdapter;
6270 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306271 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006272
Jeff Johnsone7245742012-09-05 17:12:55 -07006273 ENTER();
6274
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306275 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006276
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306277 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006278 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6280 "%s: HDD context is not valid", __func__);
6281 *dbm = 0;
6282 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006283 }
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6286 if (NULL == pAdapter)
6287 {
6288 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6289 return -ENOENT;
6290 }
6291
6292 wlan_hdd_get_classAstats(pAdapter);
6293 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6294
Jeff Johnsone7245742012-09-05 17:12:55 -07006295 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 return 0;
6297}
6298
6299static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6300 u8* mac, struct station_info *sinfo)
6301{
6302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6303 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6304 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6305 tANI_U8 rate_flags;
6306
6307 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6308 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006309
6310 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6311 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6312 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6313 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6314 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6315 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6316 tANI_U16 maxRate = 0;
6317 tANI_U16 myRate;
6318 tANI_U16 currentRate = 0;
6319 tANI_U8 maxSpeedMCS = 0;
6320 tANI_U8 maxMCSIdx = 0;
6321 tANI_U8 rateFlag = 1;
6322 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006323 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306324 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006325
Leo Chang6f8870f2013-03-26 18:11:36 -07006326#ifdef WLAN_FEATURE_11AC
6327 tANI_U32 vht_mcs_map;
6328 eDataRate11ACMaxMcs vhtMaxMcs;
6329#endif /* WLAN_FEATURE_11AC */
6330
Jeff Johnsone7245742012-09-05 17:12:55 -07006331 ENTER();
6332
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6334 (0 == ssidlen))
6335 {
6336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6337 " Invalid ssidlen, %d", __func__, ssidlen);
6338 /*To keep GUI happy*/
6339 return 0;
6340 }
6341
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306342 status = wlan_hdd_validate_context(pHddCtx);
6343
6344 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6347 "%s: HDD context is not valid", __func__);
6348 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006349 }
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6352 sinfo->filled |= STATION_INFO_SIGNAL;
6353
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006354 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6356
6357 //convert to the UI units of 100kbps
6358 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6359
6360#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006361 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 -07006362 sinfo->signal,
6363 pCfg->reportMaxLinkSpeed,
6364 myRate,
6365 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006366 (int) pCfg->linkSpeedRssiMid,
6367 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006368 (int) rate_flags,
6369 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006370#endif //LINKSPEED_DEBUG_ENABLED
6371
6372 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6373 {
6374 // we do not want to necessarily report the current speed
6375 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6376 {
6377 // report the max possible speed
6378 rssidx = 0;
6379 }
6380 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6381 {
6382 // report the max possible speed with RSSI scaling
6383 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6384 {
6385 // report the max possible speed
6386 rssidx = 0;
6387 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006388 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 {
6390 // report middle speed
6391 rssidx = 1;
6392 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006393 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6394 {
6395 // report middle speed
6396 rssidx = 2;
6397 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 else
6399 {
6400 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006401 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 }
6403 }
6404 else
6405 {
6406 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6407 hddLog(VOS_TRACE_LEVEL_ERROR,
6408 "%s: Invalid value for reportMaxLinkSpeed: %u",
6409 __func__, pCfg->reportMaxLinkSpeed);
6410 rssidx = 0;
6411 }
6412
6413 maxRate = 0;
6414
6415 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306416 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6417 OperationalRates, &ORLeng))
6418 {
6419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6420 /*To keep GUI happy*/
6421 return 0;
6422 }
6423
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 for (i = 0; i < ORLeng; i++)
6425 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006426 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 {
6428 /* Validate Rate Set */
6429 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6430 {
6431 currentRate = supported_data_rate[j].supported_rate[rssidx];
6432 break;
6433 }
6434 }
6435 /* Update MAX rate */
6436 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6437 }
6438
6439 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306440 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6441 ExtendedRates, &ERLeng))
6442 {
6443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6444 /*To keep GUI happy*/
6445 return 0;
6446 }
6447
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 for (i = 0; i < ERLeng; i++)
6449 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006450 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 {
6452 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6453 {
6454 currentRate = supported_data_rate[j].supported_rate[rssidx];
6455 break;
6456 }
6457 }
6458 /* Update MAX rate */
6459 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 /* Get MCS Rate Set -- but only if we are connected at MCS
6462 rates or if we are always reporting max speed or if we have
6463 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006464 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306466 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6467 MCSRates, &MCSLeng))
6468 {
6469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6470 /*To keep GUI happy*/
6471 return 0;
6472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006474#ifdef WLAN_FEATURE_11AC
6475 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306476 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006478 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306479 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006480 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006482 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006484 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006486 maxMCSIdx = 7;
6487 }
6488 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6489 {
6490 maxMCSIdx = 8;
6491 }
6492 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6493 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306494 //VHT20 is supporting 0~8
6495 if (rate_flags & eHAL_TX_RATE_VHT20)
6496 maxMCSIdx = 8;
6497 else
6498 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006499 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306500
6501 if (rate_flags & eHAL_TX_RATE_VHT80)
6502 {
6503 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6504 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6505 }
6506 else if (rate_flags & eHAL_TX_RATE_VHT40)
6507 {
6508 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6509 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6510 }
6511 else if (rate_flags & eHAL_TX_RATE_VHT20)
6512 {
6513 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6514 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6515 }
6516
Leo Chang6f8870f2013-03-26 18:11:36 -07006517 maxSpeedMCS = 1;
6518 if (currentRate > maxRate)
6519 {
6520 maxRate = currentRate;
6521 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306522
Leo Chang6f8870f2013-03-26 18:11:36 -07006523 }
6524 else
6525#endif /* WLAN_FEATURE_11AC */
6526 {
6527 if (rate_flags & eHAL_TX_RATE_HT40)
6528 {
6529 rateFlag |= 1;
6530 }
6531 if (rate_flags & eHAL_TX_RATE_SGI)
6532 {
6533 rateFlag |= 2;
6534 }
6535
6536 for (i = 0; i < MCSLeng; i++)
6537 {
6538 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6539 for (j = 0; j < temp; j++)
6540 {
6541 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6542 {
6543 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6544 break;
6545 }
6546 }
6547 if ((j < temp) && (currentRate > maxRate))
6548 {
6549 maxRate = currentRate;
6550 maxSpeedMCS = 1;
6551 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006553 }
6554 }
6555 }
6556
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306557 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6558 {
6559 maxRate = myRate;
6560 maxSpeedMCS = 1;
6561 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6562 }
6563
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006565 if (((maxRate < myRate) && (0 == rssidx)) ||
6566 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 {
6568 maxRate = myRate;
6569 if (rate_flags & eHAL_TX_RATE_LEGACY)
6570 {
6571 maxSpeedMCS = 0;
6572 }
6573 else
6574 {
6575 maxSpeedMCS = 1;
6576 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6577 }
6578 }
6579
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306580 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 {
6582 sinfo->txrate.legacy = maxRate;
6583#ifdef LINKSPEED_DEBUG_ENABLED
6584 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6585#endif //LINKSPEED_DEBUG_ENABLED
6586 }
6587 else
6588 {
6589 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006590#ifdef WLAN_FEATURE_11AC
6591 sinfo->txrate.nss = 1;
6592 if (rate_flags & eHAL_TX_RATE_VHT80)
6593 {
6594 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306595 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006596 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306597 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006598 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306599 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6600 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6601 }
6602 else if (rate_flags & eHAL_TX_RATE_VHT20)
6603 {
6604 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6605 }
6606#endif /* WLAN_FEATURE_11AC */
6607 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6608 {
6609 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6610 if (rate_flags & eHAL_TX_RATE_HT40)
6611 {
6612 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6613 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006614 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 if (rate_flags & eHAL_TX_RATE_SGI)
6616 {
6617 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6618 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306619
Jeff Johnson295189b2012-06-20 16:38:30 -07006620#ifdef LINKSPEED_DEBUG_ENABLED
6621 pr_info("Reporting MCS rate %d flags %x\n",
6622 sinfo->txrate.mcs,
6623 sinfo->txrate.flags );
6624#endif //LINKSPEED_DEBUG_ENABLED
6625 }
6626 }
6627 else
6628 {
6629 // report current rate instead of max rate
6630
6631 if (rate_flags & eHAL_TX_RATE_LEGACY)
6632 {
6633 //provide to the UI in units of 100kbps
6634 sinfo->txrate.legacy = myRate;
6635#ifdef LINKSPEED_DEBUG_ENABLED
6636 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6637#endif //LINKSPEED_DEBUG_ENABLED
6638 }
6639 else
6640 {
6641 //must be MCS
6642 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006643#ifdef WLAN_FEATURE_11AC
6644 sinfo->txrate.nss = 1;
6645 if (rate_flags & eHAL_TX_RATE_VHT80)
6646 {
6647 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6648 }
6649 else
6650#endif /* WLAN_FEATURE_11AC */
6651 {
6652 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6653 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 if (rate_flags & eHAL_TX_RATE_SGI)
6655 {
6656 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6657 }
6658 if (rate_flags & eHAL_TX_RATE_HT40)
6659 {
6660 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6661 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006662#ifdef WLAN_FEATURE_11AC
6663 else if (rate_flags & eHAL_TX_RATE_VHT80)
6664 {
6665 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6666 }
6667#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006668#ifdef LINKSPEED_DEBUG_ENABLED
6669 pr_info("Reporting actual MCS rate %d flags %x\n",
6670 sinfo->txrate.mcs,
6671 sinfo->txrate.flags );
6672#endif //LINKSPEED_DEBUG_ENABLED
6673 }
6674 }
6675 sinfo->filled |= STATION_INFO_TX_BITRATE;
6676
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006677 sinfo->tx_packets =
6678 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6679 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6680 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6681 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6682
6683 sinfo->tx_retries =
6684 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6685 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6686 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6687 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6688
6689 sinfo->tx_failed =
6690 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6691 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6692 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6693 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6694
6695 sinfo->filled |=
6696 STATION_INFO_TX_PACKETS |
6697 STATION_INFO_TX_RETRIES |
6698 STATION_INFO_TX_FAILED;
6699
6700 EXIT();
6701 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006702}
6703
6704static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07006705 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07006706{
6707 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306708 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306710 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006711
Jeff Johnsone7245742012-09-05 17:12:55 -07006712 ENTER();
6713
Jeff Johnson295189b2012-06-20 16:38:30 -07006714 if (NULL == pAdapter)
6715 {
6716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6717 return -ENODEV;
6718 }
6719
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306721 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306722
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306723 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6726 "%s: HDD context is not valid", __func__);
6727 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306728 }
6729
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306730 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6731 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6732 (pHddCtx->cfg_ini->fhostArpOffload) &&
6733 (eConnectionState_Associated ==
6734 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6735 {
6736 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6737 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6738 {
6739 hddLog(VOS_TRACE_LEVEL_INFO,
6740 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6741 __func__, vos_status);
6742 }
6743 }
6744
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 /**The get power cmd from the supplicant gets updated by the nl only
6746 *on successful execution of the function call
6747 *we are oppositely mapped w.r.t mode in the driver
6748 **/
6749 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6750
Jeff Johnsone7245742012-09-05 17:12:55 -07006751 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 if (VOS_STATUS_E_FAILURE == vos_status)
6753 {
6754 return -EINVAL;
6755 }
6756 return 0;
6757}
6758
6759
6760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6761static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6762 struct net_device *netdev,
6763 u8 key_index)
6764{
Jeff Johnsone7245742012-09-05 17:12:55 -07006765 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 return 0;
6767}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306768#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006769
6770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6771static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6772 struct net_device *dev,
6773 struct ieee80211_txq_params *params)
6774{
Jeff Johnsone7245742012-09-05 17:12:55 -07006775 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 return 0;
6777}
6778#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6779static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
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#endif //LINUX_VERSION_CODE
6786
6787static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6788 struct net_device *dev, u8 *mac)
6789{
6790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306791 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006792 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306793 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006794 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006795
Jeff Johnsone7245742012-09-05 17:12:55 -07006796 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306797 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 return -EINVAL;
6801 }
6802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306803 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6804 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006805
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306806 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6809 "%s: HDD context is not valid", __func__);
6810 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006811 }
6812
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 )
6816 {
6817 if( NULL == mac )
6818 {
6819 v_U16_t i;
6820 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6821 {
6822 if(pAdapter->aStaInfo[i].isUsed)
6823 {
6824 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6825 hddLog(VOS_TRACE_LEVEL_INFO,
6826 "%s: Delete STA with MAC::"
6827 "%02x:%02x:%02x:%02x:%02x:%02x",
6828 __func__,
6829 macAddr[0], macAddr[1], macAddr[2],
6830 macAddr[3], macAddr[4], macAddr[5]);
6831 hdd_softap_sta_deauth(pAdapter, macAddr);
6832 }
6833 }
6834 }
6835 else
6836 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006837
6838 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6839 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6840 {
6841 hddLog(VOS_TRACE_LEVEL_INFO,
6842 "%s: Skip this DEL STA as this is not used::"
6843 "%02x:%02x:%02x:%02x:%02x:%02x",
6844 __func__,
6845 mac[0], mac[1], mac[2],
6846 mac[3], mac[4], mac[5]);
6847 return -ENOENT;
6848 }
6849
6850 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6851 {
6852 hddLog(VOS_TRACE_LEVEL_INFO,
6853 "%s: Skip this DEL STA as deauth is in progress::"
6854 "%02x:%02x:%02x:%02x:%02x:%02x",
6855 __func__,
6856 mac[0], mac[1], mac[2],
6857 mac[3], mac[4], mac[5]);
6858 return -ENOENT;
6859 }
6860
6861 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6862
Jeff Johnson295189b2012-06-20 16:38:30 -07006863 hddLog(VOS_TRACE_LEVEL_INFO,
6864 "%s: Delete STA with MAC::"
6865 "%02x:%02x:%02x:%02x:%02x:%02x",
6866 __func__,
6867 mac[0], mac[1], mac[2],
6868 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006869
6870 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6871 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6872 {
6873 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6874 hddLog(VOS_TRACE_LEVEL_INFO,
6875 "%s: STA removal failed for ::"
6876 "%02x:%02x:%02x:%02x:%02x:%02x",
6877 __func__,
6878 mac[0], mac[1], mac[2],
6879 mac[3], mac[4], mac[5]);
6880 return -ENOENT;
6881 }
6882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 }
6884 }
6885
6886 EXIT();
6887
6888 return 0;
6889}
6890
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006891static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6892 struct net_device *dev, u8 *mac, struct station_parameters *params)
6893{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006894 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006895#ifdef FEATURE_WLAN_TDLS
6896 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006897 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006898 mask = params->sta_flags_mask;
6899
6900 set = params->sta_flags_set;
6901
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006902#ifdef WLAN_FEATURE_TDLS_DEBUG
6903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6904 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6905 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6906#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006907
6908 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6909 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006910 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006911 }
6912 }
6913#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006914 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006915}
6916
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006917
6918#ifdef FEATURE_WLAN_LFR
6919static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006920 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006921{
6922#define MAX_PMKSAIDS_IN_CACHE 8
6923 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 static tANI_U32 i; // HDD Local Cache index
6925 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6927 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306929 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006930 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306931 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932
Jeff Johnsone7245742012-09-05 17:12:55 -07006933 ENTER();
6934
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306935 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306936 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006939 return -EINVAL;
6940 }
6941
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6943 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306945 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6948 "%s: HDD context is not valid", __func__);
6949 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006950 }
6951
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306952 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006953 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6954
6955 for (j = 0; j < i; j++)
6956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306957 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006958 pmksa->bssid, WNI_CFG_BSSID_LEN))
6959 {
6960 /* BSSID matched previous entry. Overwrite it. */
6961 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306962 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006963 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306964 vos_mem_copy(PMKIDCache[j].PMKID,
6965 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006966 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306967 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006968 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969 dump_bssid(pmksa->bssid);
6970 dump_pmkid(halHandle, pmksa->pmkid);
6971 break;
6972 }
6973 }
6974
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006975 /* Check we compared all entries,if then take the first slot now */
6976 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6977
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006978 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306979 {
6980 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6981 vos_mem_copy(PMKIDCache[i].BSSID,
6982 pmksa->bssid, ETHER_ADDR_LEN);
6983 vos_mem_copy(PMKIDCache[i].PMKID,
6984 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006985 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006987 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006988 dump_bssid(pmksa->bssid);
6989 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306990 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006991 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306992 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006993 }
6994
6995
6996 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306997 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006998 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007000 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307002 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7003 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007004 i );
7005 return 0;
7006}
7007
7008
7009static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007010 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007011{
Jeff Johnsone7245742012-09-05 17:12:55 -07007012 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007013 // TODO: Implement this later.
7014 return 0;
7015}
7016
7017static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7018{
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#endif
7024
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007025#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307026static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007027 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7028{
7029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7030 hdd_station_ctx_t *pHddStaCtx;
7031
7032 if (NULL == pAdapter)
7033 {
7034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7035 return -ENODEV;
7036 }
7037
7038 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7039
7040 // Added for debug on reception of Re-assoc Req.
7041 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307043 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007044 ftie->ie_len);
7045 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7046 }
7047
7048#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307049 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007050 ftie->ie_len);
7051#endif
7052
7053 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307054 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7055 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007056 ftie->ie_len);
7057 return 0;
7058}
7059#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007060
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307061#ifdef FEATURE_WLAN_SCAN_PNO
7062
7063void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7064 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7065{
7066 int ret;
7067 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7068 hdd_context_t *pHddCtx;
7069
7070 if (NULL == pAdapter)
7071 {
7072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7073 "%s: HDD adapter is Null", __func__);
7074 return ;
7075 }
7076
7077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7078 if (NULL == pHddCtx)
7079 {
7080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7081 "%s: HDD context is Null!!!", __func__);
7082 return ;
7083 }
7084
7085 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7086
7087 if (0 > ret)
7088 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7089
7090 cfg80211_sched_scan_results(pHddCtx->wiphy);
7091}
7092
7093/*
7094 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7095 * NL interface to enable PNO
7096 */
7097static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7098 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7099{
7100 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7101 tpSirPNOScanReq pPnoRequest = NULL;
7102 hdd_context_t *pHddCtx;
7103 tHalHandle hHal;
7104 v_U32_t i, indx, num_ch;
7105 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7106 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7107 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7108 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307109 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307110
7111 if (NULL == pAdapter)
7112 {
7113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7114 "%s: HDD adapter is Null", __func__);
7115 return -ENODEV;
7116 }
7117
7118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307119 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307120
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307121 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307122 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7124 "%s: HDD context is not valid", __func__);
7125 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307126 }
7127
7128 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7129 if (NULL == hHal)
7130 {
7131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7132 "%s: HAL context is Null!!!", __func__);
7133 return -EAGAIN;
7134 }
7135
7136 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7137 if (NULL == pPnoRequest)
7138 {
7139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7140 "%s: vos_mem_malloc failed", __func__);
7141 return -ENODEV;
7142 }
7143
7144 pPnoRequest->enable = 1; /*Enable PNO */
7145 pPnoRequest->ucNetworksCount = request->n_match_sets;
7146
7147 if (( !pPnoRequest->ucNetworksCount ) ||
7148 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7149 {
7150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7151 "Network input is not correct");
7152 goto error;
7153 }
7154
7155 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7156 {
7157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7158 "Incorrect number of channels");
7159 goto error;
7160 }
7161
7162 /* Framework provides one set of channels(all)
7163 * common for all saved profile */
7164 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7165 channels_allowed, &num_channels_allowed))
7166 {
7167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7168 "%s: failed to get valid channel list", __func__);
7169 goto error;
7170 }
7171 /* Checking each channel against allowed channel list */
7172 num_ch = 0;
7173 for (i = 0; i < request->n_channels; i++)
7174 {
7175 for (indx = 0; indx < num_channels_allowed; indx++)
7176 {
7177 if (request->channels[i]->hw_value == channels_allowed[indx])
7178 {
7179 valid_ch[num_ch++] = request->channels[i]->hw_value;
7180 break ;
7181 }
7182 }
7183 }
7184
7185 /* Filling per profile params */
7186 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7187 {
7188 pPnoRequest->aNetworks[i].ssId.length =
7189 request->match_sets[i].ssid.ssid_len;
7190
7191 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7192 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7193 {
7194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7195 "SSID Len %d is not correct for network %d",
7196 pPnoRequest->aNetworks[i].ssId.length, i);
7197 goto error;
7198 }
7199
7200 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7201 request->match_sets[i].ssid.ssid,
7202 request->match_sets[i].ssid.ssid_len);
7203 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7204 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7205 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7206
7207 /*Copying list of valid channel into request */
7208 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7209 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7210
7211 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7212 }
7213
7214 /* framework provides interval in ms */
7215 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7216 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7217 (request->interval)/1000;
7218 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7219 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7220
7221 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7222 pPnoRequest, pAdapter->sessionId,
7223 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7224 if (eHAL_STATUS_SUCCESS != status)
7225 {
7226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7227 "Failed to enable PNO");
7228 goto error;
7229 }
7230
7231error:
7232 vos_mem_free(pPnoRequest);
7233 return status;
7234}
7235
7236/*
7237 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7238 * NL interface to disable PNO
7239 */
7240static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7241 struct net_device *dev)
7242{
7243 eHalStatus status = eHAL_STATUS_FAILURE;
7244 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7245 hdd_context_t *pHddCtx;
7246 tHalHandle hHal;
7247 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307248 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307249
7250 ENTER();
7251
7252 if (NULL == pAdapter)
7253 {
7254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7255 "%s: HDD adapter is Null", __func__);
7256 return -ENODEV;
7257 }
7258
7259 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307260 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307261
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307262 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307263 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7265 "%s: HDD context is not valid", __func__);
7266 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307267 }
7268
7269 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7270 if (NULL == hHal)
7271 {
7272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7273 "%s: HAL context is Null!!!", __func__);
7274 return -EAGAIN;
7275 }
7276
7277 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7278 if (NULL == pPnoRequest)
7279 {
7280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7281 "%s: vos_mem_malloc failed", __func__);
7282 return -ENODEV;
7283 }
7284
7285 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7286 pPnoRequest->enable = 0; /* Disable PNO */
7287 pPnoRequest->ucNetworksCount = 0;
7288
7289 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7290 pAdapter->sessionId,
7291 NULL, pAdapter);
7292 if (eHAL_STATUS_SUCCESS != status)
7293 {
7294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7295 "Failed to disabled PNO");
7296 }
7297
7298 vos_mem_free(pPnoRequest);
7299
7300 EXIT();
7301 return status;
7302}
7303
7304#endif /*FEATURE_WLAN_SCAN_PNO*/
7305
7306
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007307#ifdef FEATURE_WLAN_TDLS
7308static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7309 u8 *peer, u8 action_code, u8 dialog_token,
7310 u16 status_code, const u8 *buf, size_t len)
7311{
7312
7313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7314 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007315 u8 peerMac[6];
7316 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007317 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007318 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007319 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007320
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007321 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007324 "Invalid arguments");
7325 return -EINVAL;
7326 }
7327
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007328 if (pHddCtx->isLogpInProgress)
7329 {
7330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7331 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007332 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007333 return -EBUSY;
7334 }
7335
Hoonki Lee27511902013-03-14 18:19:06 -07007336 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007337 {
Hoonki Lee27511902013-03-14 18:19:06 -07007338 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7339 "%s: TDLS mode is disabled OR not enabled in FW."
7340 MAC_ADDRESS_STR " action %d declined.",
7341 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007342 return -ENOTSUPP;
7343 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007344
Hoonki Lee27511902013-03-14 18:19:06 -07007345 /* other than teardown frame, other mgmt frames are not sent if disabled */
7346 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7347 {
7348 /* if tdls_mode is disabled to respond to peer's request */
7349 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7350 {
7351 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7352 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007353 " TDLS mode is disabled. action %d declined.",
7354 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007355
7356 return -ENOTSUPP;
7357 }
7358 }
7359
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007360 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7361 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007362 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007363 {
7364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007365 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007366 " TDLS setup is ongoing. action %d declined.",
7367 __func__, MAC_ADDR_ARRAY(peer), action_code);
7368 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007369 }
7370 }
7371
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007372 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7373 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007374 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007375 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007376 {
7377 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7378 we return error code at 'add_station()'. Hence we have this
7379 check again in addtion to add_station().
7380 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007381 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007382 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7384 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007385 " TDLS Max peer already connected. action %d declined.",
7386 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007387 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007388 }
7389 else
7390 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007391 /* maximum reached. tweak to send error code to peer and return
7392 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007393 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7395 "%s: " MAC_ADDRESS_STR
7396 " TDLS Max peer already connected send response status %d",
7397 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007398 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007399 /* fall through to send setup resp with failure status
7400 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007401 }
7402 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007403 else
7404 {
7405 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007406 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007407 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007408 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007410 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7411 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007412 return -EPERM;
7413 }
7414 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007415 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007416 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007417
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007418#ifdef WLAN_FEATURE_TDLS_DEBUG
7419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007420 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7421 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7422 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007423#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007424
Hoonki Leea34dd892013-02-05 22:56:02 -08007425 /*Except teardown responder will not be used so just make 0*/
7426 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007427 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007428 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007429
7430 hddTdlsPeer_t *pTdlsPeer;
7431 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7432
7433 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7434 responder = pTdlsPeer->is_responder;
7435 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007436 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7438 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7439 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7440 dialog_token, status_code, len);
7441 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007442 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007443 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007444
Hoonki Lee14621352013-04-16 17:51:19 -07007445 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7446 (SIR_MAC_TDLS_DIS_RSP == action_code))
7447 {
7448 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7449 {
7450 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7451 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7452 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7453 }
7454 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7455 }
7456
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007457 /* make sure doesn't call send_mgmt() while it is pending */
7458 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7459 {
7460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7461 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7462 __func__, MAC_ADDR_ARRAY(peer), action_code);
7463 return -EBUSY;
7464 }
7465
7466 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007467 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7468
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007469 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007470 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007471
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007472 if (VOS_STATUS_SUCCESS != status)
7473 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7475 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007476 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007477 wlan_hdd_tdls_check_bmps(pAdapter);
7478 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007479 }
7480
Hoonki Leed37cbb32013-04-20 00:31:14 -07007481 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7482 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7483
7484 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007485 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7487 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7488 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007489 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007490 wlan_hdd_tdls_check_bmps(pAdapter);
7491 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007492 }
7493
Gopichand Nakkala05922802013-03-14 12:23:19 -07007494 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007495 {
7496 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007497 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007498 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007499
Hoonki Leea34dd892013-02-05 22:56:02 -08007500 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7501 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007502 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007503 }
7504 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7505 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007506 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007507 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007508
7509 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007510error:
7511 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7512 because we already know that this transaction will be failed,
7513 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7514 to be safe, do not change the state mahine.
7515 */
7516 if(max_sta_failed == 0 &&
7517 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7518 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7519 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007520}
7521
7522static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7523 u8 *peer, enum nl80211_tdls_operation oper)
7524{
7525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7526 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307527 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307528#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7529 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307530 tANI_U8 staIdx;
7531#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007532#ifdef WLAN_FEATURE_TDLS_DEBUG
7533 const char *tdls_oper_str[]= {
7534 "NL80211_TDLS_DISCOVERY_REQ",
7535 "NL80211_TDLS_SETUP",
7536 "NL80211_TDLS_TEARDOWN",
7537 "NL80211_TDLS_ENABLE_LINK",
7538 "NL80211_TDLS_DISABLE_LINK",
7539 "NL80211_TDLS_UNKONW_OPER"};
7540#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007541 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007542
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307543 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007544 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007546 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007547 return -EINVAL;
7548 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007549
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 status = wlan_hdd_validate_context(pHddCtx);
7551
7552 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7555 "%s: HDD context is not valid", __func__);
7556 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007557 }
7558
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007559 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7560
7561 if ( NULL == pTdlsPeer ) {
7562 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7563 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7564 return -EINVAL;
7565 }
7566
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007567#ifdef WLAN_FEATURE_TDLS_DEBUG
7568 if((int)oper > 4)
7569 oper = 5;
7570
7571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007572 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7573 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007574 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007575#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007576
7577 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007578 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007579 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007581 "TDLS Disabled in INI OR not enabled in FW. "
7582 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007583 return -ENOTSUPP;
7584 }
7585
7586 switch (oper) {
7587 case NL80211_TDLS_ENABLE_LINK:
7588 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007589 VOS_STATUS status;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307590 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007591
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007592 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7593 {
7594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7595 MAC_ADDRESS_STR " failed",
7596 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7597 return -EINVAL;
7598 }
7599
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007600 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007601 {
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307602 if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
7603 return -EINVAL;
7604 }
7605 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
7606
7607 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
7608 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
7609 /* Send TDLS peer UAPSD capabilities to the firmware and
7610 * register with the TL on after the response for this operation
7611 * is received .
7612 */
7613 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
7614 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
7615 if (status <= 0)
7616 {
7617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7618 "%s: Link Establish Request Faled Status %ld",
7619 __func__, status);
7620 return -EINVAL;
7621 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007622 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307623 /* Mark TDLS client Authenticated .*/
7624 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7625 pTdlsPeer->staId,
7626 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007627 if (VOS_STATUS_SUCCESS == status)
7628 {
Hoonki Lee14621352013-04-16 17:51:19 -07007629 if (pTdlsPeer->is_responder == 0)
7630 {
7631 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7632
7633 wlan_hdd_tdls_timer_restart(pAdapter,
7634 &pTdlsPeer->initiatorWaitTimeoutTimer,
7635 WAIT_TIME_TDLS_INITIATOR);
7636 /* suspend initiator TX until it receives direct packet from the
7637 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7638 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7639 &staId, NULL);
7640 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007641 wlan_hdd_tdls_increment_peer_count(pAdapter);
7642 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007643 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307644
7645 /* Update TL about the UAPSD masks , to route the packets to firmware */
7646 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7647 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VO )
7648 {
7649 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7650 pTdlsPeer->staId,
7651 WLANTL_AC_VO,
7652 7,
7653 7,
7654 0,
7655 0,
7656 WLANTL_BI_DIR );
7657
7658 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7659 }
7660
7661 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7662 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VI )
7663 {
7664 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7665 pTdlsPeer->staId,
7666 WLANTL_AC_VI,
7667 5,
7668 5,
7669 0,
7670 0,
7671 WLANTL_BI_DIR );
7672
7673 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7674 }
7675
7676 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7677 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BK )
7678 {
7679 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7680 pTdlsPeer->staId,
7681 WLANTL_AC_BK,
7682 2,
7683 2,
7684 0,
7685 0,
7686 WLANTL_BI_DIR );
7687
7688 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7689 }
7690
7691 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7692 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BE )
7693 {
7694 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7695 pTdlsPeer->staId,
7696 WLANTL_AC_BE,
7697 3,
7698 3,
7699 0,
7700 0,
7701 WLANTL_BI_DIR );
7702
7703 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7704 }
7705
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007706 }
7707
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007708 }
7709 break;
7710 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007711 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007712 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007713 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007714 long status;
7715
7716 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7717
Lee Hoonkic1262f22013-01-24 21:59:00 -08007718 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7719 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007720
7721 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7722 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7723 if (status <= 0)
7724 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007725 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7727 "%s: Del station failed status %ld",
7728 __func__, status);
7729 return -EPERM;
7730 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007731 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007732 }
7733 else
7734 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7736 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007737 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307738#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7739 if (pHddTdlsCtx->defer_link_lost_indication)
7740 {
7741 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7742 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7743 {
7744 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7745 if ( 0 != status)
7746 {
7747 hddLog(VOS_TRACE_LEVEL_ERROR,
7748 "%s wlan_hdd_disconnect failure, returned %d \n",
7749 __func__, (int)status );
7750 return -EINVAL;
7751 }
7752 }
7753 }
7754#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007755 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007756 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007757 case NL80211_TDLS_TEARDOWN:
7758 case NL80211_TDLS_SETUP:
7759 case NL80211_TDLS_DISCOVERY_REQ:
7760 /* We don't support in-driver setup/teardown/discovery */
7761 return -ENOTSUPP;
7762 default:
7763 return -ENOTSUPP;
7764 }
7765 return 0;
7766}
Chilam NG571c65a2013-01-19 12:27:36 +05307767
7768int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7769 struct net_device *dev, u8 *peer)
7770{
7771 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7772 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7773
7774 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7775 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7776}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007777#endif
7778
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307779#ifdef WLAN_FEATURE_GTK_OFFLOAD
7780/*
7781 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7782 * Callback rountine called upon receiving response for
7783 * get offload info
7784 */
7785void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7786 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7787{
7788
7789 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7790
7791 ENTER();
7792
7793 if (NULL == pAdapter)
7794 {
7795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7796 "%s: HDD adapter is Null", __func__);
7797 return ;
7798 }
7799
7800 if (NULL == pGtkOffloadGetInfoRsp)
7801 {
7802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7803 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7804 return ;
7805 }
7806
7807 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7808 {
7809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7810 "%s: wlan Failed to get replay counter value",
7811 __func__);
7812 return ;
7813 }
7814
7815 /* Update replay counter to NL */
7816 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7817 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7818}
7819
7820/*
7821 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7822 * This function is used to offload GTK rekeying job to the firmware.
7823 */
7824int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7825 struct cfg80211_gtk_rekey_data *data)
7826{
7827 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7828 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7829 hdd_station_ctx_t *pHddStaCtx;
7830 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307831 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307832 tpSirGtkOffloadParams pGtkOffloadReqParams;
7833 eHalStatus status = eHAL_STATUS_FAILURE;
7834
7835 ENTER();
7836
7837 if (NULL == pAdapter)
7838 {
7839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7840 "%s: HDD adapter is Null", __func__);
7841 return -ENODEV;
7842 }
7843
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307844 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307845
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307846 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307847 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7849 "%s: HDD context is not valid", __func__);
7850 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307851 }
7852
7853 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7854 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7855 if (NULL == hHal)
7856 {
7857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7858 "%s: HAL context is Null!!!", __func__);
7859 return -EAGAIN;
7860 }
7861
7862 pGtkOffloadReqParams =
7863 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7864
7865 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7866 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7867 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7868 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7869 WNI_CFG_BSSID_LEN);
7870 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7871 sizeof (tANI_U64));
7872
7873 if (TRUE == pHddCtx->hdd_wlan_suspended)
7874 {
7875 /* if wlan is suspended, enable GTK offload directly from here */
7876 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7877 pAdapter->sessionId);
7878
7879 if (eHAL_STATUS_SUCCESS != status)
7880 {
7881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7882 "%s: sme_SetGTKOffload failed, returned %d",
7883 __func__, status);
7884 return status;
7885 }
7886 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7888 "%s: sme_SetGTKOffload successfull", __func__);
7889 }
7890 else
7891 {
7892 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7894 "%s: wlan not suspended GTKOffload request is stored",
7895 __func__);
7896 return eHAL_STATUS_SUCCESS;
7897 }
7898 return status;
7899}
7900#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7901
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307902/*
7903 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7904 * This function is used to set access control policy
7905 */
7906static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7907 struct net_device *dev, const struct cfg80211_acl_data *params)
7908{
7909 int i;
7910 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7911 hdd_hostapd_state_t *pHostapdState;
7912 tsap_Config_t *pConfig;
7913 v_CONTEXT_t pVosContext = NULL;
7914 hdd_context_t *pHddCtx;
7915 int status;
7916
7917 ENTER();
7918
7919 if (NULL == pAdapter)
7920 {
7921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7922 "%s: HDD adapter is Null", __func__);
7923 return -ENODEV;
7924 }
7925
7926 if (NULL == params)
7927 {
7928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7929 "%s: params is Null", __func__);
7930 return -EINVAL;
7931 }
7932
7933 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7934 status = wlan_hdd_validate_context(pHddCtx);
7935
7936 if (0 != status)
7937 {
7938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7939 "%s: HDD context is not valid", __func__);
7940 return status;
7941 }
7942
7943 pVosContext = pHddCtx->pvosContext;
7944 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7945
7946 if (NULL == pHostapdState)
7947 {
7948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7949 "%s: pHostapdState is Null", __func__);
7950 return -EINVAL;
7951 }
7952
7953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7954 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7955
7956 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7957 {
7958 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7959
7960 /* default value */
7961 pConfig->num_accept_mac = 0;
7962 pConfig->num_deny_mac = 0;
7963
7964 /**
7965 * access control policy
7966 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7967 * listed in hostapd.deny file.
7968 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7969 * listed in hostapd.accept file.
7970 */
7971 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7972 {
7973 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7974 }
7975 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
7976 {
7977 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7978 }
7979 else
7980 {
7981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7982 "%s:Acl Policy : %d is not supported",
7983 __func__, params->acl_policy);
7984 return -ENOTSUPP;
7985 }
7986
7987 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
7988 {
7989 pConfig->num_accept_mac = params->n_acl_entries;
7990 for (i = 0; i < params->n_acl_entries; i++)
7991 {
7992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7993 "** Add ACL MAC entry %i in WhiletList :"
7994 MAC_ADDRESS_STR, i,
7995 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7996
7997 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
7998 sizeof(qcmacaddr));
7999 }
8000 }
8001 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
8002 {
8003 pConfig->num_deny_mac = params->n_acl_entries;
8004 for (i = 0; i < params->n_acl_entries; i++)
8005 {
8006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8007 "** Add ACL MAC entry %i in BlackList :"
8008 MAC_ADDRESS_STR, i,
8009 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8010
8011 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
8012 sizeof(qcmacaddr));
8013 }
8014 }
8015
8016 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
8017 {
8018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8019 "%s: SAP Set Mac Acl fail", __func__);
8020 return -EINVAL;
8021 }
8022 }
8023 else
8024 {
8025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8026 "%s: Invalid device_mode = %d",
8027 __func__, pAdapter->device_mode);
8028 return -EINVAL;
8029 }
8030
8031 return 0;
8032}
8033
Jeff Johnson295189b2012-06-20 16:38:30 -07008034/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308035static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07008036{
8037 .add_virtual_intf = wlan_hdd_add_virtual_intf,
8038 .del_virtual_intf = wlan_hdd_del_virtual_intf,
8039 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
8040 .change_station = wlan_hdd_change_station,
8041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8042 .add_beacon = wlan_hdd_cfg80211_add_beacon,
8043 .del_beacon = wlan_hdd_cfg80211_del_beacon,
8044 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008045#else
8046 .start_ap = wlan_hdd_cfg80211_start_ap,
8047 .change_beacon = wlan_hdd_cfg80211_change_beacon,
8048 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07008049#endif
8050 .change_bss = wlan_hdd_cfg80211_change_bss,
8051 .add_key = wlan_hdd_cfg80211_add_key,
8052 .get_key = wlan_hdd_cfg80211_get_key,
8053 .del_key = wlan_hdd_cfg80211_del_key,
8054 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008055#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008057#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 .scan = wlan_hdd_cfg80211_scan,
8059 .connect = wlan_hdd_cfg80211_connect,
8060 .disconnect = wlan_hdd_cfg80211_disconnect,
8061 .join_ibss = wlan_hdd_cfg80211_join_ibss,
8062 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
8063 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
8064 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
8065 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
8067 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
8068 .mgmt_tx = wlan_hdd_action,
8069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8070 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
8071 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
8072 .set_txq_params = wlan_hdd_set_txq_params,
8073#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 .get_station = wlan_hdd_cfg80211_get_station,
8075 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
8076 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008077 .add_station = wlan_hdd_cfg80211_add_station,
8078#ifdef FEATURE_WLAN_LFR
8079 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
8080 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
8081 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
8082#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008083#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8084 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8085#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008086#ifdef FEATURE_WLAN_TDLS
8087 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8088 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8089#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308090#ifdef WLAN_FEATURE_GTK_OFFLOAD
8091 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8092#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308093#ifdef FEATURE_WLAN_SCAN_PNO
8094 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8095 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8096#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308097 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008098};
8099