blob: aa3cbb1755f36e8a2ca003400c4ae3b93bec1eb3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20*/
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22/**========================================================================
23
24 \file wlan_hdd_cfg80211.c
25
26 \brief WLAN Host Device Driver implementation
27
Gopichand Nakkala747461f2013-04-24 19:24:45 +053028 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053030 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32 ========================================================================*/
33
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070034/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070035
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070036 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070046 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070047 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070052 ==========================================================================*/
53
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include <linux/version.h>
56#include <linux/module.h>
57#include <linux/kernel.h>
58#include <linux/init.h>
59#include <linux/wireless.h>
60#include <wlan_hdd_includes.h>
61#include <net/arp.h>
62#include <net/cfg80211.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_wowl.h>
65#include <aniGlobal.h>
66#include "ccmApi.h"
67#include "sirParams.h"
68#include "dot11f.h"
69#include "wlan_hdd_assoc.h"
70#include "wlan_hdd_wext.h"
71#include "sme_Api.h"
72#include "wlan_hdd_p2p.h"
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_hostapd.h"
75#include "sapInternal.h"
76#include "wlan_hdd_softap_tx_rx.h"
77#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053078#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053079#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080#ifdef WLAN_BTAMP_FEATURE
81#include "bap_hdd_misc.h"
82#endif
83#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053086#include "wlan_hdd_wmm.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080087#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053088#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089
90#define g_mode_rates_size (12)
91#define a_mode_rates_size (8)
92#define FREQ_BASE_80211G (2407)
93#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070094#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070095#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
96 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
97
98#define HDD2GHZCHAN(freq, chan, flag) { \
99 .band = IEEE80211_BAND_2GHZ, \
100 .center_freq = (freq), \
101 .hw_value = (chan),\
102 .flags = (flag), \
103 .max_antenna_gain = 0 ,\
104 .max_power = 30, \
105}
106
107#define HDD5GHZCHAN(freq, chan, flag) { \
108 .band = IEEE80211_BAND_5GHZ, \
109 .center_freq = (freq), \
110 .hw_value = (chan),\
111 .flags = (flag), \
112 .max_antenna_gain = 0 ,\
113 .max_power = 30, \
114}
115
116#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
117{\
118 .bitrate = rate, \
119 .hw_value = rate_id, \
120 .flags = flag, \
121}
122
Lee Hoonkic1262f22013-01-24 21:59:00 -0800123#ifndef WLAN_FEATURE_TDLS_DEBUG
124#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
125#else
126#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
127#endif
128
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530129#ifdef WLAN_FEATURE_VOWIFI_11R
130#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
131#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
132#endif
133
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530134static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700135{
136 WLAN_CIPHER_SUITE_WEP40,
137 WLAN_CIPHER_SUITE_WEP104,
138 WLAN_CIPHER_SUITE_TKIP,
139#ifdef FEATURE_WLAN_CCX
140#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
141 WLAN_CIPHER_SUITE_KRK,
142 WLAN_CIPHER_SUITE_CCMP,
143#else
144 WLAN_CIPHER_SUITE_CCMP,
145#endif
146#ifdef FEATURE_WLAN_WAPI
147 WLAN_CIPHER_SUITE_SMS4,
148#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700149#ifdef WLAN_FEATURE_11W
150 WLAN_CIPHER_SUITE_AES_CMAC,
151#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700152};
153
154static inline int is_broadcast_ether_addr(const u8 *addr)
155{
156 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
157 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
158}
159
160static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530161{
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 HDD2GHZCHAN(2412, 1, 0) ,
163 HDD2GHZCHAN(2417, 2, 0) ,
164 HDD2GHZCHAN(2422, 3, 0) ,
165 HDD2GHZCHAN(2427, 4, 0) ,
166 HDD2GHZCHAN(2432, 5, 0) ,
167 HDD2GHZCHAN(2437, 6, 0) ,
168 HDD2GHZCHAN(2442, 7, 0) ,
169 HDD2GHZCHAN(2447, 8, 0) ,
170 HDD2GHZCHAN(2452, 9, 0) ,
171 HDD2GHZCHAN(2457, 10, 0) ,
172 HDD2GHZCHAN(2462, 11, 0) ,
173 HDD2GHZCHAN(2467, 12, 0) ,
174 HDD2GHZCHAN(2472, 13, 0) ,
175 HDD2GHZCHAN(2484, 14, 0) ,
176};
177
Jeff Johnson295189b2012-06-20 16:38:30 -0700178static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
179{
180 HDD2GHZCHAN(2412, 1, 0) ,
181 HDD2GHZCHAN(2437, 6, 0) ,
182 HDD2GHZCHAN(2462, 11, 0) ,
183};
Jeff Johnson295189b2012-06-20 16:38:30 -0700184
185static struct ieee80211_channel hdd_channels_5_GHZ[] =
186{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700187 HDD5GHZCHAN(4920, 240, 0) ,
188 HDD5GHZCHAN(4940, 244, 0) ,
189 HDD5GHZCHAN(4960, 248, 0) ,
190 HDD5GHZCHAN(4980, 252, 0) ,
191 HDD5GHZCHAN(5040, 208, 0) ,
192 HDD5GHZCHAN(5060, 212, 0) ,
193 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 HDD5GHZCHAN(5180, 36, 0) ,
195 HDD5GHZCHAN(5200, 40, 0) ,
196 HDD5GHZCHAN(5220, 44, 0) ,
197 HDD5GHZCHAN(5240, 48, 0) ,
198 HDD5GHZCHAN(5260, 52, 0) ,
199 HDD5GHZCHAN(5280, 56, 0) ,
200 HDD5GHZCHAN(5300, 60, 0) ,
201 HDD5GHZCHAN(5320, 64, 0) ,
202 HDD5GHZCHAN(5500,100, 0) ,
203 HDD5GHZCHAN(5520,104, 0) ,
204 HDD5GHZCHAN(5540,108, 0) ,
205 HDD5GHZCHAN(5560,112, 0) ,
206 HDD5GHZCHAN(5580,116, 0) ,
207 HDD5GHZCHAN(5600,120, 0) ,
208 HDD5GHZCHAN(5620,124, 0) ,
209 HDD5GHZCHAN(5640,128, 0) ,
210 HDD5GHZCHAN(5660,132, 0) ,
211 HDD5GHZCHAN(5680,136, 0) ,
212 HDD5GHZCHAN(5700,140, 0) ,
213 HDD5GHZCHAN(5745,149, 0) ,
214 HDD5GHZCHAN(5765,153, 0) ,
215 HDD5GHZCHAN(5785,157, 0) ,
216 HDD5GHZCHAN(5805,161, 0) ,
217 HDD5GHZCHAN(5825,165, 0) ,
218};
219
220static struct ieee80211_rate g_mode_rates[] =
221{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530222 HDD_G_MODE_RATETAB(10, 0x1, 0),
223 HDD_G_MODE_RATETAB(20, 0x2, 0),
224 HDD_G_MODE_RATETAB(55, 0x4, 0),
225 HDD_G_MODE_RATETAB(110, 0x8, 0),
226 HDD_G_MODE_RATETAB(60, 0x10, 0),
227 HDD_G_MODE_RATETAB(90, 0x20, 0),
228 HDD_G_MODE_RATETAB(120, 0x40, 0),
229 HDD_G_MODE_RATETAB(180, 0x80, 0),
230 HDD_G_MODE_RATETAB(240, 0x100, 0),
231 HDD_G_MODE_RATETAB(360, 0x200, 0),
232 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530234};
Jeff Johnson295189b2012-06-20 16:38:30 -0700235
236static struct ieee80211_rate a_mode_rates[] =
237{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 HDD_G_MODE_RATETAB(540, 0x800, 0),
246};
247
248static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
249{
250 .channels = hdd_channels_2_4_GHZ,
251 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
252 .band = IEEE80211_BAND_2GHZ,
253 .bitrates = g_mode_rates,
254 .n_bitrates = g_mode_rates_size,
255 .ht_cap.ht_supported = 1,
256 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
257 | IEEE80211_HT_CAP_GRN_FLD
258 | IEEE80211_HT_CAP_DSSSCCK40
259 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
260 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
261 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
262 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
263 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
264 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
265};
266
Jeff Johnson295189b2012-06-20 16:38:30 -0700267static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
268{
269 .channels = hdd_social_channels_2_4_GHZ,
270 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
271 .band = IEEE80211_BAND_2GHZ,
272 .bitrates = g_mode_rates,
273 .n_bitrates = g_mode_rates_size,
274 .ht_cap.ht_supported = 1,
275 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
276 | IEEE80211_HT_CAP_GRN_FLD
277 | IEEE80211_HT_CAP_DSSSCCK40
278 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
279 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
280 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
281 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
282 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
283 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
284};
Jeff Johnson295189b2012-06-20 16:38:30 -0700285
286static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
287{
288 .channels = hdd_channels_5_GHZ,
289 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
290 .band = IEEE80211_BAND_5GHZ,
291 .bitrates = a_mode_rates,
292 .n_bitrates = a_mode_rates_size,
293 .ht_cap.ht_supported = 1,
294 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
295 | IEEE80211_HT_CAP_GRN_FLD
296 | IEEE80211_HT_CAP_DSSSCCK40
297 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
298 | IEEE80211_HT_CAP_SGI_40
299 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
300 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
301 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
302 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
303 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
304 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
305};
306
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530307/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 TX/RX direction for each kind of interface */
309static const struct ieee80211_txrx_stypes
310wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
311 [NL80211_IFTYPE_STATION] = {
312 .tx = 0xffff,
313 .rx = BIT(SIR_MAC_MGMT_ACTION) |
314 BIT(SIR_MAC_MGMT_PROBE_REQ),
315 },
316 [NL80211_IFTYPE_AP] = {
317 .tx = 0xffff,
318 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
320 BIT(SIR_MAC_MGMT_PROBE_REQ) |
321 BIT(SIR_MAC_MGMT_DISASSOC) |
322 BIT(SIR_MAC_MGMT_AUTH) |
323 BIT(SIR_MAC_MGMT_DEAUTH) |
324 BIT(SIR_MAC_MGMT_ACTION),
325 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700326 [NL80211_IFTYPE_ADHOC] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
329 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
330 BIT(SIR_MAC_MGMT_PROBE_REQ) |
331 BIT(SIR_MAC_MGMT_DISASSOC) |
332 BIT(SIR_MAC_MGMT_AUTH) |
333 BIT(SIR_MAC_MGMT_DEAUTH) |
334 BIT(SIR_MAC_MGMT_ACTION),
335 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 [NL80211_IFTYPE_P2P_CLIENT] = {
337 .tx = 0xffff,
338 .rx = BIT(SIR_MAC_MGMT_ACTION) |
339 BIT(SIR_MAC_MGMT_PROBE_REQ),
340 },
341 [NL80211_IFTYPE_P2P_GO] = {
342 /* This is also same as for SoftAP */
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
346 BIT(SIR_MAC_MGMT_PROBE_REQ) |
347 BIT(SIR_MAC_MGMT_DISASSOC) |
348 BIT(SIR_MAC_MGMT_AUTH) |
349 BIT(SIR_MAC_MGMT_DEAUTH) |
350 BIT(SIR_MAC_MGMT_ACTION),
351 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700352};
353
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800355static const struct ieee80211_iface_limit
356wlan_hdd_iface_limit[] = {
357 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800358 /* max = 3 ; Our driver create two interfaces during driver init
359 * wlan0 and p2p0 interfaces. p2p0 is considered as station
360 * interface until a group is formed. In JB architecture, once the
361 * group is formed, interface type of p2p0 is changed to P2P GO or
362 * Client.
363 * When supplicant remove the group, it first issue a set interface
364 * cmd to change the mode back to Station. In JB this works fine as
365 * we advertize two station type interface during driver init.
366 * Some vendors create separate interface for P2P GO/Client,
367 * after group formation(Third one). But while group remove
368 * supplicant first tries to change the mode(3rd interface) to STATION
369 * But as we advertized only two sta type interfaces nl80211 was
370 * returning error for the third one which was leading to failure in
371 * delete interface. Ideally while removing the group, supplicant
372 * should not try to change the 3rd interface mode to Station type.
373 * Till we get a fix in wpa_supplicant, we advertize max STA
374 * interface type to 3
375 */
376 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800377 .types = BIT(NL80211_IFTYPE_STATION),
378 },
379 {
380 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700381 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800382 },
383 {
384 .max = 1,
385 .types = BIT(NL80211_IFTYPE_P2P_GO) |
386 BIT(NL80211_IFTYPE_P2P_CLIENT),
387 },
388};
389
390/* By default, only single channel concurrency is allowed */
391static struct ieee80211_iface_combination
392wlan_hdd_iface_combination = {
393 .limits = wlan_hdd_iface_limit,
394 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /*
396 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
397 * and p2p0 interfaces during driver init
398 * Some vendors create separate interface for P2P operations.
399 * wlan0: STA interface
400 * p2p0: P2P Device interface, action frames goes
401 * through this interface.
402 * p2p-xx: P2P interface, After GO negotiation this interface is
403 * created for p2p operations(GO/CLIENT interface).
404 */
405 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
407 .beacon_int_infra_match = false,
408};
409#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800410
Jeff Johnson295189b2012-06-20 16:38:30 -0700411static struct cfg80211_ops wlan_hdd_cfg80211_ops;
412
413/* Data rate 100KBPS based on IE Index */
414struct index_data_rate_type
415{
416 v_U8_t beacon_rate_index;
417 v_U16_t supported_rate[4];
418};
419
420/* 11B, 11G Rate table include Basic rate and Extended rate
421 The IDX field is the rate index
422 The HI field is the rate when RSSI is strong or being ignored
423 (in this case we report actual rate)
424 The MID field is the rate when RSSI is moderate
425 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
426 The LO field is the rate when RSSI is low
427 (in this case we don't report rates, actual current rate used)
428 */
429static const struct
430{
431 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700432 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700433} supported_data_rate[] =
434{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700435/* IDX HI HM LM LO (RSSI-based index */
436 {2, { 10, 10, 10, 0}},
437 {4, { 20, 20, 10, 0}},
438 {11, { 55, 20, 10, 0}},
439 {12, { 60, 55, 20, 0}},
440 {18, { 90, 55, 20, 0}},
441 {22, {110, 55, 20, 0}},
442 {24, {120, 90, 60, 0}},
443 {36, {180, 120, 60, 0}},
444 {44, {220, 180, 60, 0}},
445 {48, {240, 180, 90, 0}},
446 {66, {330, 180, 90, 0}},
447 {72, {360, 240, 90, 0}},
448 {96, {480, 240, 120, 0}},
449 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700450};
451
452/* MCS Based rate table */
453static struct index_data_rate_type supported_mcs_rate[] =
454{
455/* MCS L20 L40 S20 S40 */
456 {0, {65, 135, 72, 150}},
457 {1, {130, 270, 144, 300}},
458 {2, {195, 405, 217, 450}},
459 {3, {260, 540, 289, 600}},
460 {4, {390, 810, 433, 900}},
461 {5, {520, 1080, 578, 1200}},
462 {6, {585, 1215, 650, 1350}},
463 {7, {650, 1350, 722, 1500}}
464};
465
Leo Chang6f8870f2013-03-26 18:11:36 -0700466#ifdef WLAN_FEATURE_11AC
467
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530468#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700469
470struct index_vht_data_rate_type
471{
472 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530473 v_U16_t supported_VHT80_rate[2];
474 v_U16_t supported_VHT40_rate[2];
475 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700476};
477
478typedef enum
479{
480 DATA_RATE_11AC_MAX_MCS_7,
481 DATA_RATE_11AC_MAX_MCS_8,
482 DATA_RATE_11AC_MAX_MCS_9,
483 DATA_RATE_11AC_MAX_MCS_NA
484} eDataRate11ACMaxMcs;
485
486/* MCS Based VHT rate table */
487static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
488{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530489/* MCS L80 S80 L40 S40 L20 S40*/
490 {0, {293, 325}, {135, 150}, {65, 72}},
491 {1, {585, 650}, {270, 300}, {130, 144}},
492 {2, {878, 975}, {405, 450}, {195, 217}},
493 {3, {1170, 1300}, {540, 600}, {260, 289}},
494 {4, {1755, 1950}, {810, 900}, {390, 433}},
495 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
496 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
497 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
498 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
499 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700500};
501#endif /* WLAN_FEATURE_11AC */
502
Jeff Johnson295189b2012-06-20 16:38:30 -0700503extern struct net_device_ops net_ops_struct;
504
505/*
506 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530507 * This function is called by hdd_wlan_startup()
508 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700509 * This function is used to initialize and register wiphy structure.
510 */
511struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
512{
513 struct wiphy *wiphy;
514 ENTER();
515
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530516 /*
517 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 */
519 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
520
521 if (!wiphy)
522 {
523 /* Print error and jump into err label and free the memory */
524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
525 return NULL;
526 }
527
528 return wiphy;
529}
530
531/*
532 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530533 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700534 * private ioctl to change the band value
535 */
536int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
537{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530538 int i, j;
539 eNVChannelEnabledType channelEnabledState;
540
Jeff Johnsone7245742012-09-05 17:12:55 -0700541 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530542 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700543 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530544
545 if (NULL == wiphy->bands[i])
546 {
547 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
548 __func__, i);
549 continue;
550 }
551
552 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
553 {
554 struct ieee80211_supported_band *band = wiphy->bands[i];
555
556 channelEnabledState = vos_nv_getChannelEnabledState(
557 band->channels[j].hw_value);
558
559 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
560 {
561 // Enable Social channels for P2P
562 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
563 NV_CHANNEL_ENABLE == channelEnabledState)
564 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
565 else
566 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
567 continue;
568 }
569 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
570 {
571 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
572 continue;
573 }
574
575 if (NV_CHANNEL_DISABLE == channelEnabledState ||
576 NV_CHANNEL_INVALID == channelEnabledState)
577 {
578 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
579 }
580 else if (NV_CHANNEL_DFS == channelEnabledState)
581 {
582 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
583 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
584 }
585 else
586 {
587 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
588 |IEEE80211_CHAN_RADAR);
589 }
590 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700591 }
592 return 0;
593}
594/*
595 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530596 * This function is called by hdd_wlan_startup()
597 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 * This function is used to initialize and register wiphy structure.
599 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530600int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700601 struct wiphy *wiphy,
602 hdd_config_t *pCfg
603 )
604{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530605
606 int i, j;
607
Jeff Johnsone7245742012-09-05 17:12:55 -0700608 ENTER();
609
Jeff Johnson295189b2012-06-20 16:38:30 -0700610 /* Now bind the underlying wlan device with wiphy */
611 set_wiphy_dev(wiphy, dev);
612
613 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
614
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700615 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700616
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700617#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700618 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
619 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
620 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700621 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700622#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700623#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
624 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800625#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700626 || pCfg->isFastRoamIniFeatureEnabled
627#endif
628#ifdef FEATURE_WLAN_CCX
629 || pCfg->isCcxIniFeatureEnabled
630#endif
631 )
632 {
633 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
634 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800635#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800636#ifdef FEATURE_WLAN_TDLS
637 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
638 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
639#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530640#ifdef FEATURE_WLAN_SCAN_PNO
641 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
642 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
643 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
644#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800645
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700646 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
647 driver can still register regulatory callback and
648 it will get CRDA setting in wiphy->band[], but
649 driver need to determine what to do with both
650 regulatory settings */
651 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700652
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530653 wiphy->max_scan_ssids = MAX_SCAN_SSID;
654
Jeff Johnson295189b2012-06-20 16:38:30 -0700655 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
656
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530657 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
658
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530660 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 | BIT(NL80211_IFTYPE_P2P_CLIENT)
663 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 | BIT(NL80211_IFTYPE_AP);
665
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800667 if( pCfg->enableMCC )
668 {
669 /* Currently, supports up to two channels */
670 wlan_hdd_iface_combination.num_different_channels = 2;
671
672 if( !pCfg->allowMCCGODiffBI )
673 wlan_hdd_iface_combination.beacon_int_infra_match = true;
674
675 }
676 wiphy->iface_combinations = &wlan_hdd_iface_combination;
677 wiphy->n_iface_combinations = 1;
678#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800679
Jeff Johnson295189b2012-06-20 16:38:30 -0700680 /* Before registering we need to update the ht capabilitied based
681 * on ini values*/
682 if( !pCfg->ShortGI20MhzEnable )
683 {
684 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
685 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
686 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
687 }
688
689 if( !pCfg->ShortGI40MhzEnable )
690 {
691 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
692 }
693
694 if( !pCfg->nChannelBondingMode5GHz )
695 {
696 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
697 }
698
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530699 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
700 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
701
702 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
703 {
704
705 if (NULL == wiphy->bands[i])
706 {
707 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
708 __func__, i);
709 continue;
710 }
711
712 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
713 {
714 struct ieee80211_supported_band *band = wiphy->bands[i];
715
716 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
717 {
718 // Enable social channels for P2P
719 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
720 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
721 else
722 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
723 continue;
724 }
725 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
726 {
727 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
728 continue;
729 }
730 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 }
732 /*Initialise the supported cipher suite details*/
733 wiphy->cipher_suites = hdd_cipher_suites;
734 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
735
736 /*signal strength in mBm (100*dBm) */
737 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
738
739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700740 wiphy->max_remain_on_channel_duration = 1000;
741#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700742
743 /* Register our wiphy dev with cfg80211 */
744 if (0 > wiphy_register(wiphy))
745 {
746 /* print eror */
747 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
748 return -EIO;
749 }
750
751 EXIT();
752 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530753}
Jeff Johnson295189b2012-06-20 16:38:30 -0700754
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700755/* In this function we will try to get default country code from crda.
756 If the gCrdaDefaultCountryCode is configured in ini file,
757 we will try to call user space crda to get the regulatory settings for
758 that country. We will timeout if we can't get it from crda.
759 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
760*/
761int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
762{
763 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
764 if (memcmp(pCfg->crdaDefaultCountryCode,
765 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
766 {
767 init_completion(&pHddCtx->driver_crda_req);
768 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
769 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
770 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700771 /* if the country is not found from current regulatory.bin,
772 fall back to world domain */
773 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
774 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700775 }
776 return 0;
777}
778
Jeff Johnson295189b2012-06-20 16:38:30 -0700779/* In this function we will do all post VOS start initialization.
780 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530781 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700782*/
783void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
784{
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
786 /* Register for all P2P action, public action etc frames */
787 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
788
Jeff Johnsone7245742012-09-05 17:12:55 -0700789 ENTER();
790
Jeff Johnson295189b2012-06-20 16:38:30 -0700791 /* Right now we are registering these frame when driver is getting
792 initialized. Once we will move to 2.6.37 kernel, in which we have
793 frame register ops, we will move this code as a part of that */
794 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530795 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700796 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
797
798 /* GAS Initial Response */
799 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
800 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530801
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 /* GAS Comeback Request */
803 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
804 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
805
806 /* GAS Comeback Response */
807 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
808 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
809
810 /* P2P Public Action */
811 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530812 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 P2P_PUBLIC_ACTION_FRAME_SIZE );
814
815 /* P2P Action */
816 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
817 (v_U8_t*)P2P_ACTION_FRAME,
818 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700819
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530820 /* WNM BSS Transition Request frame */
821 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
822 (v_U8_t*)WNM_BSS_ACTION_FRAME,
823 WNM_BSS_ACTION_FRAME_SIZE );
824
Chet Lanctot186b5732013-03-18 10:26:30 -0700825#ifdef WLAN_FEATURE_11W
826 /* SA Query Response Action Frame */
827 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
828 (v_U8_t*)SA_QUERY_FRAME_RSP,
829 SA_QUERY_FRAME_RSP_SIZE );
830#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700831}
832
833void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
834{
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
836 /* Register for all P2P action, public action etc frames */
837 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
838
Jeff Johnsone7245742012-09-05 17:12:55 -0700839 ENTER();
840
Jeff Johnson295189b2012-06-20 16:38:30 -0700841 /* Right now we are registering these frame when driver is getting
842 initialized. Once we will move to 2.6.37 kernel, in which we have
843 frame register ops, we will move this code as a part of that */
844 /* GAS Initial Request */
845
846 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
847 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
848
849 /* GAS Initial Response */
850 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
851 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530852
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 /* GAS Comeback Request */
854 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
855 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
856
857 /* GAS Comeback Response */
858 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
859 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
860
861 /* P2P Public Action */
862 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530863 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700864 P2P_PUBLIC_ACTION_FRAME_SIZE );
865
866 /* P2P Action */
867 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
868 (v_U8_t*)P2P_ACTION_FRAME,
869 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700870
871#ifdef WLAN_FEATURE_11W
872 /* SA Query Response Action Frame */
873 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
874 (v_U8_t*)SA_QUERY_FRAME_RSP,
875 SA_QUERY_FRAME_RSP_SIZE );
876#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700877}
878
879#ifdef FEATURE_WLAN_WAPI
880void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
881 const u8 *mac_addr, u8 *key , int key_Len)
882{
883 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
884 tCsrRoamSetKey setKey;
885 v_BOOL_t isConnected = TRUE;
886 int status = 0;
887 v_U32_t roamId= 0xFF;
888 tANI_U8 *pKeyPtr = NULL;
889 int n = 0;
890
891 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
892 __func__,pAdapter->device_mode);
893
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530894 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 setKey.keyId = key_index; // Store Key ID
896 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
897 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
898 setKey.paeRole = 0 ; // the PAE role
899 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
900 {
901 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
902 }
903 else
904 {
905 isConnected = hdd_connIsConnected(pHddStaCtx);
906 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
907 }
908 setKey.keyLength = key_Len;
909 pKeyPtr = setKey.Key;
910 memcpy( pKeyPtr, key, key_Len);
911
912 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
913 __func__, key_Len);
914 for (n = 0 ; n < key_Len; n++)
915 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
916 __func__,n,setKey.Key[n]);
917
918 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
919 if ( isConnected )
920 {
921 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
922 pAdapter->sessionId, &setKey, &roamId );
923 }
924 if ( status != 0 )
925 {
926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
927 "[%4d] sme_RoamSetKey returned ERROR status= %d",
928 __LINE__, status );
929 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
930 }
931}
932#endif /* FEATURE_WLAN_WAPI*/
933
934#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530935int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 beacon_data_t **ppBeacon,
937 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530939int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700940 beacon_data_t **ppBeacon,
941 struct cfg80211_beacon_data *params,
942 int dtim_period)
943#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944{
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 int size;
946 beacon_data_t *beacon = NULL;
947 beacon_data_t *old = NULL;
948 int head_len,tail_len;
949
Jeff Johnsone7245742012-09-05 17:12:55 -0700950 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 if (params->head && !params->head_len)
952 return -EINVAL;
953
954 old = pAdapter->sessionCtx.ap.beacon;
955
956 if (!params->head && !old)
957 return -EINVAL;
958
959 if (params->tail && !params->tail_len)
960 return -EINVAL;
961
962#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
963 /* Kernel 3.0 is not updating dtim_period for set beacon */
964 if (!params->dtim_period)
965 return -EINVAL;
966#endif
967
968 if(params->head)
969 head_len = params->head_len;
970 else
971 head_len = old->head_len;
972
973 if(params->tail || !old)
974 tail_len = params->tail_len;
975 else
976 tail_len = old->tail_len;
977
978 size = sizeof(beacon_data_t) + head_len + tail_len;
979
980 beacon = kzalloc(size, GFP_KERNEL);
981
982 if( beacon == NULL )
983 return -ENOMEM;
984
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700986 if(params->dtim_period || !old )
987 beacon->dtim_period = params->dtim_period;
988 else
989 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700990#else
991 if(dtim_period || !old )
992 beacon->dtim_period = dtim_period;
993 else
994 beacon->dtim_period = old->dtim_period;
995#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530996
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
998 beacon->tail = beacon->head + head_len;
999 beacon->head_len = head_len;
1000 beacon->tail_len = tail_len;
1001
1002 if(params->head) {
1003 memcpy (beacon->head,params->head,beacon->head_len);
1004 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301005 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 if(old)
1007 memcpy (beacon->head,old->head,beacon->head_len);
1008 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301009
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 if(params->tail) {
1011 memcpy (beacon->tail,params->tail,beacon->tail_len);
1012 }
1013 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301014 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 memcpy (beacon->tail,old->tail,beacon->tail_len);
1016 }
1017
1018 *ppBeacon = beacon;
1019
1020 kfree(old);
1021
1022 return 0;
1023
1024}
Jeff Johnson295189b2012-06-20 16:38:30 -07001025
1026v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1027{
1028 int left = length;
1029 v_U8_t *ptr = pIes;
1030 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301031
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301033 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 elem_id = ptr[0];
1035 elem_len = ptr[1];
1036 left -= 2;
1037 if(elem_len > left)
1038 {
1039 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001040 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001041 eid,elem_len,left);
1042 return NULL;
1043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301044 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 {
1046 return ptr;
1047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301048
Jeff Johnson295189b2012-06-20 16:38:30 -07001049 left -= elem_len;
1050 ptr += (elem_len + 2);
1051 }
1052 return NULL;
1053}
1054
Jeff Johnson295189b2012-06-20 16:38:30 -07001055/* Check if rate is 11g rate or not */
1056static int wlan_hdd_rate_is_11g(u8 rate)
1057{
1058 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
1059 u8 i;
1060 for (i = 0; i < 8; i++)
1061 {
1062 if(rate == gRateArray[i])
1063 return TRUE;
1064 }
1065 return FALSE;
1066}
1067
1068/* Check for 11g rate and set proper 11g only mode */
1069static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1070 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1071{
1072 u8 i, num_rates = pIe[0];
1073
1074 pIe += 1;
1075 for ( i = 0; i < num_rates; i++)
1076 {
1077 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1078 {
1079 /* If rate set have 11g rate than change the mode to 11G */
1080 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1081 if (pIe[i] & BASIC_RATE_MASK)
1082 {
1083 /* If we have 11g rate as basic rate, it means mode
1084 is 11g only mode.
1085 */
1086 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1087 *pCheckRatesfor11g = FALSE;
1088 }
1089 }
1090 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1091 {
1092 *require_ht = TRUE;
1093 }
1094 }
1095 return;
1096}
1097
1098static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1099{
1100 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1101 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1102 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1103 u8 checkRatesfor11g = TRUE;
1104 u8 require_ht = FALSE;
1105 u8 *pIe=NULL;
1106
1107 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1108
1109 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1110 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1111 if (pIe != NULL)
1112 {
1113 pIe += 1;
1114 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1115 &pConfig->SapHw_mode);
1116 }
1117
1118 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1119 WLAN_EID_EXT_SUPP_RATES);
1120 if (pIe != NULL)
1121 {
1122
1123 pIe += 1;
1124 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1125 &pConfig->SapHw_mode);
1126 }
1127
1128 if( pConfig->channel > 14 )
1129 {
1130 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1131 }
1132
1133 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1134 WLAN_EID_HT_CAPABILITY);
1135
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301136 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 {
1138 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1139 if(require_ht)
1140 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1141 }
1142}
1143
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301144static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1145 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1146{
1147 v_U8_t ielen = 0;
1148 v_U8_t *pIe = NULL;
1149 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1150
1151 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1152 pBeacon->tail, pBeacon->tail_len);
1153
1154 if (pIe)
1155 {
1156 ielen = pIe[1] + 2;
1157 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1158 {
1159 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1160 }
1161 else
1162 {
1163 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1164 return -EINVAL;
1165 }
1166 *total_ielen += ielen;
1167 }
1168 return 0;
1169}
1170
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001171#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001172static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1173 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001174#else
1175static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1176 struct cfg80211_beacon_data *params)
1177#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001178{
1179 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301180 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001182 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001183
1184 genie = vos_mem_malloc(MAX_GENIE_LEN);
1185
1186 if(genie == NULL) {
1187
1188 return -ENOMEM;
1189 }
1190
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301191 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1192 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301194 ret = -EINVAL;
1195 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 }
1197
1198#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301199 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1200 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1201 {
1202 ret = -EINVAL;
1203 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 }
1205#endif
1206
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301207 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1208 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001209 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301210 ret = -EINVAL;
1211 goto done;
1212 }
1213
1214 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1215 {
1216 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1217 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301219 ret = -EINVAL;
1220 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001223
1224 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1225 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1226 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1227 {
1228 hddLog(LOGE,
1229 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001230 ret = -EINVAL;
1231 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 }
1233
1234 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1235 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1236 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1237 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1238 ==eHAL_STATUS_FAILURE)
1239 {
1240 hddLog(LOGE,
1241 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001242 ret = -EINVAL;
1243 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001244 }
1245
1246 // Added for ProResp IE
1247 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1248 {
1249 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1250 u8 probe_rsp_ie_len[3] = {0};
1251 u8 counter = 0;
1252 /* Check Probe Resp Length if it is greater then 255 then Store
1253 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1254 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1255 Store More then 255 bytes into One Variable.
1256 */
1257 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1258 {
1259 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1260 {
1261 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1262 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1263 }
1264 else
1265 {
1266 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1267 rem_probe_resp_ie_len = 0;
1268 }
1269 }
1270
1271 rem_probe_resp_ie_len = 0;
1272
1273 if (probe_rsp_ie_len[0] > 0)
1274 {
1275 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1276 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1277 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1278 probe_rsp_ie_len[0], NULL,
1279 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1280 {
1281 hddLog(LOGE,
1282 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001283 ret = -EINVAL;
1284 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001285 }
1286 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1287 }
1288
1289 if (probe_rsp_ie_len[1] > 0)
1290 {
1291 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1292 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1293 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1294 probe_rsp_ie_len[1], NULL,
1295 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1296 {
1297 hddLog(LOGE,
1298 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001299 ret = -EINVAL;
1300 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 }
1302 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1303 }
1304
1305 if (probe_rsp_ie_len[2] > 0)
1306 {
1307 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1308 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1309 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1310 probe_rsp_ie_len[2], NULL,
1311 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1312 {
1313 hddLog(LOGE,
1314 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001315 ret = -EINVAL;
1316 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 }
1318 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1319 }
1320
1321 if (probe_rsp_ie_len[1] == 0 )
1322 {
1323 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1324 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1325 eANI_BOOLEAN_FALSE) )
1326 {
1327 hddLog(LOGE,
1328 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1329 }
1330 }
1331
1332 if (probe_rsp_ie_len[2] == 0 )
1333 {
1334 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1335 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1336 eANI_BOOLEAN_FALSE) )
1337 {
1338 hddLog(LOGE,
1339 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1340 }
1341 }
1342
1343 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1344 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1345 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1346 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1347 == eHAL_STATUS_FAILURE)
1348 {
1349 hddLog(LOGE,
1350 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001351 ret = -EINVAL;
1352 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 }
1354 }
1355 else
1356 {
1357 // Reset WNI_CFG_PROBE_RSP Flags
1358 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1359
1360 hddLog(VOS_TRACE_LEVEL_INFO,
1361 "%s: No Probe Response IE received in set beacon",
1362 __func__);
1363 }
1364
1365 // Added for AssocResp IE
1366 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1367 {
1368 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1369 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1370 params->assocresp_ies_len, NULL,
1371 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1372 {
1373 hddLog(LOGE,
1374 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001375 ret = -EINVAL;
1376 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 }
1378
1379 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1380 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1381 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1382 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1383 == eHAL_STATUS_FAILURE)
1384 {
1385 hddLog(LOGE,
1386 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001387 ret = -EINVAL;
1388 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001389 }
1390 }
1391 else
1392 {
1393 hddLog(VOS_TRACE_LEVEL_INFO,
1394 "%s: No Assoc Response IE received in set beacon",
1395 __func__);
1396
1397 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1398 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1399 eANI_BOOLEAN_FALSE) )
1400 {
1401 hddLog(LOGE,
1402 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1403 }
1404 }
1405
Jeff Johnsone7245742012-09-05 17:12:55 -07001406done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001407 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301408 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001409}
Jeff Johnson295189b2012-06-20 16:38:30 -07001410
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301411/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 * FUNCTION: wlan_hdd_validate_operation_channel
1413 * called by wlan_hdd_cfg80211_start_bss() and
1414 * wlan_hdd_cfg80211_set_channel()
1415 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301416 * channel list.
1417 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001418VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001419{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301420
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 v_U32_t num_ch = 0;
1422 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1423 u32 indx = 0;
1424 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301425 v_U8_t fValidChannel = FALSE, count = 0;
1426 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301427
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1429
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301430 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301432 /* Validate the channel */
1433 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001434 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301435 if ( channel == rfChannels[count].channelNum )
1436 {
1437 fValidChannel = TRUE;
1438 break;
1439 }
1440 }
1441 if (fValidChannel != TRUE)
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 "%s: Invalid Channel [%d]", __func__, channel);
1445 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 }
1447 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301448 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301450 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1451 valid_ch, &num_ch))
1452 {
1453 hddLog(VOS_TRACE_LEVEL_ERROR,
1454 "%s: failed to get valid channel list", __func__);
1455 return VOS_STATUS_E_FAILURE;
1456 }
1457 for (indx = 0; indx < num_ch; indx++)
1458 {
1459 if (channel == valid_ch[indx])
1460 {
1461 break;
1462 }
1463 }
1464
1465 if (indx >= num_ch)
1466 {
1467 hddLog(VOS_TRACE_LEVEL_ERROR,
1468 "%s: Invalid Channel [%d]", __func__, channel);
1469 return VOS_STATUS_E_FAILURE;
1470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 }
1472 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301473
Jeff Johnson295189b2012-06-20 16:38:30 -07001474}
1475
Viral Modi3a32cc52013-02-08 11:14:52 -08001476/**
1477 * FUNCTION: wlan_hdd_cfg80211_set_channel
1478 * This function is used to set the channel number
1479 */
1480static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1481 struct ieee80211_channel *chan,
1482 enum nl80211_channel_type channel_type
1483 )
1484{
1485 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001486 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001487 hdd_adapter_t *pAdapter = NULL;
1488 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301489 hdd_context_t *pHddCtx;
1490 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001491
1492 ENTER();
1493
1494 if( NULL == dev )
1495 {
1496 hddLog(VOS_TRACE_LEVEL_ERROR,
1497 "%s: Called with dev = NULL.\n", __func__);
1498 return -ENODEV;
1499 }
1500 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1501
1502 hddLog(VOS_TRACE_LEVEL_INFO,
1503 "%s: device_mode = %d freq = %d \n",__func__,
1504 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301505
1506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1507 status = wlan_hdd_validate_context(pHddCtx);
1508
1509 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1512 "%s: HDD context is not valid", __func__);
1513 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001514 }
1515
1516 /*
1517 * Do freq to chan conversion
1518 * TODO: for 11a
1519 */
1520
1521 channel = ieee80211_frequency_to_channel(freq);
1522
1523 /* Check freq range */
1524 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1525 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1526 {
1527 hddLog(VOS_TRACE_LEVEL_ERROR,
1528 "%s: Channel [%d] is outside valid range from %d to %d\n",
1529 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1530 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1531 return -EINVAL;
1532 }
1533
1534 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1535
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301536 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1537 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001538 {
1539 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 "%s: Invalid Channel [%d] \n", __func__, channel);
1543 return -EINVAL;
1544 }
1545 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1546 "%s: set channel to [%d] for device mode =%d",
1547 __func__, channel,pAdapter->device_mode);
1548 }
1549 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001550 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001551 )
1552 {
1553 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1554 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1555 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1556
1557 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1558 {
1559 /* Link is up then return cant set channel*/
1560 hddLog( VOS_TRACE_LEVEL_ERROR,
1561 "%s: IBSS Associated, can't set the channel\n", __func__);
1562 return -EINVAL;
1563 }
1564
1565 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1566 pHddStaCtx->conn_info.operationChannel = channel;
1567 pRoamProfile->ChannelInfo.ChannelList =
1568 &pHddStaCtx->conn_info.operationChannel;
1569 }
1570 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001571 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001572 )
1573 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301574 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1575 {
1576 if(VOS_STATUS_SUCCESS !=
1577 wlan_hdd_validate_operation_channel(pAdapter,channel))
1578 {
1579 hddLog(VOS_TRACE_LEVEL_ERROR,
1580 "%s: Invalid Channel [%d] \n", __func__, channel);
1581 return -EINVAL;
1582 }
1583 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1584 }
1585 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001586 {
1587 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1588
1589 /* If auto channel selection is configured as enable/ 1 then ignore
1590 channel set by supplicant
1591 */
1592 if ( cfg_param->apAutoChannelSelection )
1593 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301594 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1595 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001596 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1597 "%s: set channel to auto channel (0) for device mode =%d",
1598 __func__, pAdapter->device_mode);
1599 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301600 else
1601 {
1602 if(VOS_STATUS_SUCCESS !=
1603 wlan_hdd_validate_operation_channel(pAdapter,channel))
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 "%s: Invalid Channel [%d] \n", __func__, channel);
1607 return -EINVAL;
1608 }
1609 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1610 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001611 }
1612 }
1613 else
1614 {
1615 hddLog(VOS_TRACE_LEVEL_FATAL,
1616 "%s: Invalid device mode failed to set valid channel", __func__);
1617 return -EINVAL;
1618 }
1619 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301620 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001621}
1622
Jeff Johnson295189b2012-06-20 16:38:30 -07001623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1624static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1625 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001626#else
1627static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1628 struct cfg80211_beacon_data *params,
1629 const u8 *ssid, size_t ssid_len,
1630 enum nl80211_hidden_ssid hidden_ssid)
1631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001632{
1633 tsap_Config_t *pConfig;
1634 beacon_data_t *pBeacon = NULL;
1635 struct ieee80211_mgmt *pMgmt_frame;
1636 v_U8_t *pIe=NULL;
1637 v_U16_t capab_info;
1638 eCsrAuthType RSNAuthType;
1639 eCsrEncryptionType RSNEncryptType;
1640 eCsrEncryptionType mcRSNEncryptType;
1641 int status = VOS_STATUS_SUCCESS;
1642 tpWLAN_SAPEventCB pSapEventCallback;
1643 hdd_hostapd_state_t *pHostapdState;
1644 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1645 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301646 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001647 struct qc_mac_acl_entry *acl_entry = NULL;
1648 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001650
1651 ENTER();
1652
1653 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1654
1655 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1656
1657 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1658
1659 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1660
1661 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1662
1663 //channel is already set in the set_channel Call back
1664 //pConfig->channel = pCommitConfig->channel;
1665
1666 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301667 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1669
1670 pConfig->dtim_period = pBeacon->dtim_period;
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1673 pConfig->dtim_period);
1674
1675
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001676 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001677 {
1678 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001680 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001681 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001682 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001683 pConfig->ieee80211d = 1;
1684 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1685 sme_setRegInfo(hHal, pConfig->countryCode);
1686 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001688 else
1689 {
1690 pConfig->ieee80211d = 0;
1691 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301692 /*
1693 * If auto channel is configured i.e. channel is 0,
1694 * so skip channel validation.
1695 */
1696 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1697 {
1698 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1699 {
1700 hddLog(VOS_TRACE_LEVEL_ERROR,
1701 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1702 return -EINVAL;
1703 }
1704 }
1705 else
1706 {
1707 if(1 != pHddCtx->is_dynamic_channel_range_set)
1708 {
1709 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1710 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1711 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1712 }
1713 pHddCtx->is_dynamic_channel_range_set = 0;
1714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001716 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001717 {
1718 pConfig->ieee80211d = 0;
1719 }
1720 pConfig->authType = eSAP_AUTO_SWITCH;
1721
1722 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301723
1724 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001725 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1726
1727 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1728
1729 /*Set wps station to configured*/
1730 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1731
1732 if(pIe)
1733 {
1734 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1735 {
1736 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1737 return -EINVAL;
1738 }
1739 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1740 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001741 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 /* Check 15 bit of WPS IE as it contain information for wps state
1743 * WPS state
1744 */
1745 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1746 {
1747 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1748 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1749 {
1750 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1751 }
1752 }
1753 }
1754 else
1755 {
1756 pConfig->wps_state = SAP_WPS_DISABLED;
1757 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301758 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001759
1760 pConfig->RSNWPAReqIELength = 0;
1761 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301762 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 WLAN_EID_RSN);
1764 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301765 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1767 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1768 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301769 /* The actual processing may eventually be more extensive than
1770 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 * by the app.
1772 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301773 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1775 &RSNEncryptType,
1776 &mcRSNEncryptType,
1777 &RSNAuthType,
1778 pConfig->pRSNWPAReqIE[1]+2,
1779 pConfig->pRSNWPAReqIE );
1780
1781 if( VOS_STATUS_SUCCESS == status )
1782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301783 /* Now copy over all the security attributes you have
1784 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 * */
1786 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1787 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1788 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1789 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301790 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 "EncryptionType = %d mcEncryptionType = %d\n"),
1792 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1793 }
1794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301795
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1797 pBeacon->tail, pBeacon->tail_len);
1798
1799 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1800 {
1801 if (pConfig->pRSNWPAReqIE)
1802 {
1803 /*Mixed mode WPA/WPA2*/
1804 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1805 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1806 }
1807 else
1808 {
1809 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1810 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1811 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301812 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1814 &RSNEncryptType,
1815 &mcRSNEncryptType,
1816 &RSNAuthType,
1817 pConfig->pRSNWPAReqIE[1]+2,
1818 pConfig->pRSNWPAReqIE );
1819
1820 if( VOS_STATUS_SUCCESS == status )
1821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301822 /* Now copy over all the security attributes you have
1823 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 * */
1825 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1826 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1827 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1828 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301829 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 "EncryptionType = %d mcEncryptionType = %d\n"),
1831 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1832 }
1833 }
1834 }
1835
Jeff Johnson4416a782013-03-25 14:17:50 -07001836 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1837 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1838 return -EINVAL;
1839 }
1840
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1842
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001843#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 if (params->ssid != NULL)
1845 {
1846 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1847 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1848 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1849 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1850 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001851#else
1852 if (ssid != NULL)
1853 {
1854 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1855 pConfig->SSIDinfo.ssid.length = ssid_len;
1856 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1857 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1858 }
1859#endif
1860
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301861 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001862 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301863
Jeff Johnson295189b2012-06-20 16:38:30 -07001864 /* default value */
1865 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1866 pConfig->num_accept_mac = 0;
1867 pConfig->num_deny_mac = 0;
1868
1869 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1870 pBeacon->tail, pBeacon->tail_len);
1871
1872 /* pIe for black list is following form:
1873 type : 1 byte
1874 length : 1 byte
1875 OUI : 4 bytes
1876 acl type : 1 byte
1877 no of mac addr in black list: 1 byte
1878 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301879 */
1880 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 {
1882 pConfig->SapMacaddr_acl = pIe[6];
1883 pConfig->num_deny_mac = pIe[7];
1884 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1885 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301886 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1887 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1889 for (i = 0; i < pConfig->num_deny_mac; i++)
1890 {
1891 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1892 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301893 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 }
1895 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1896 pBeacon->tail, pBeacon->tail_len);
1897
1898 /* pIe for white list is following form:
1899 type : 1 byte
1900 length : 1 byte
1901 OUI : 4 bytes
1902 acl type : 1 byte
1903 no of mac addr in white list: 1 byte
1904 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301905 */
1906 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 {
1908 pConfig->SapMacaddr_acl = pIe[6];
1909 pConfig->num_accept_mac = pIe[7];
1910 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1911 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301912 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1913 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1915 for (i = 0; i < pConfig->num_accept_mac; i++)
1916 {
1917 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1918 acl_entry++;
1919 }
1920 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1923
Jeff Johnsone7245742012-09-05 17:12:55 -07001924#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001925 /* Overwrite the hostapd setting for HW mode only for 11ac.
1926 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1927 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1928 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1929 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301930 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001931 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1932 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001933 {
1934 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07001935
1936 /* Disable VHT support in 2.4 GHz band */
1937 if (pConfig->channel <= 14 &&
1938 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
1939 {
1940 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1941 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001942 }
1943#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301944
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001945 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1946 {
1947 sme_SelectCBMode(hHal,
1948 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1949 pConfig->channel);
1950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 // ht_capab is not what the name conveys,this is used for protection bitmap
1952 pConfig->ht_capab =
1953 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1954
1955 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1956 {
1957 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1958 return -EINVAL;
1959 }
1960
1961 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301962 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1964 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301965 pConfig->obssProtEnabled =
1966 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001967
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301968 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001969 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301970 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1972 (int)pConfig->channel);
1973 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301974 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1975 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301977 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1979 pConfig->protEnabled, pConfig->obssProtEnabled);
1980
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301981 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 {
1983 //Bss already started. just return.
1984 //TODO Probably it should update some beacon params.
1985 hddLog( LOGE, "Bss Already started...Ignore the request");
1986 EXIT();
1987 return 0;
1988 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301989
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 pConfig->persona = pHostapdAdapter->device_mode;
1991
1992 pSapEventCallback = hdd_hostapd_SAPEventCB;
1993 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1994 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1995 {
1996 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1997 return -EINVAL;
1998 }
1999
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302000 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2002
2003 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302004
Jeff Johnson295189b2012-06-20 16:38:30 -07002005 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302006 {
2007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 ("ERROR: HDD vos wait for single_event failed!!\n"));
2009 VOS_ASSERT(0);
2010 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302011
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 //Succesfully started Bss update the state bit.
2013 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2014
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002015#ifdef WLAN_FEATURE_P2P_DEBUG
2016 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2017 {
2018 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2019 {
2020 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2021 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002022 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002023 }
2024 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2025 {
2026 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2027 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002028 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002029 }
2030 }
2031#endif
2032
Jeff Johnson295189b2012-06-20 16:38:30 -07002033 pHostapdState->bCommit = TRUE;
2034 EXIT();
2035
2036 return 0;
2037}
2038
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002039#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302040static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2041 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 struct beacon_parameters *params)
2043{
2044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302045 hdd_context_t *pHddCtx;
2046 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002047
2048 ENTER();
2049
2050 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2051
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302052 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2053 status = wlan_hdd_validate_context(pHddCtx);
2054
2055 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2058 "%s: HDD context is not valid", __func__);
2059 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002060 }
2061
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302062 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 )
2065 {
2066 beacon_data_t *old,*new;
2067
2068 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302069
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 if (old)
2071 return -EALREADY;
2072
2073 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2074
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302075 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 {
2077 hddLog(VOS_TRACE_LEVEL_FATAL,
2078 "%s:Error!!! Allocating the new beacon\n",__func__);
2079 return -EINVAL;
2080 }
2081
2082 pAdapter->sessionCtx.ap.beacon = new;
2083
2084 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2085 }
2086
2087 EXIT();
2088 return status;
2089}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302090
2091static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002092 struct net_device *dev,
2093 struct beacon_parameters *params)
2094{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302096 hdd_context_t *pHddCtx;
2097 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002098
2099 ENTER();
2100
2101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2102 __func__,pAdapter->device_mode);
2103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2105 status = wlan_hdd_validate_context(pHddCtx);
2106
2107 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002108 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2110 "%s: HDD context is not valid", __func__);
2111 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002112 }
2113
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302116 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 {
2118 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302119
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302121
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 if (!old)
2123 return -ENOENT;
2124
2125 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2126
2127 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302128 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 "%s: Error!!! Allocating the new beacon\n",__func__);
2130 return -EINVAL;
2131 }
2132
2133 pAdapter->sessionCtx.ap.beacon = new;
2134
2135 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2136 }
2137
2138 EXIT();
2139 return status;
2140}
2141
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002142#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2143
2144#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002145static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2146 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002147#else
2148static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2149 struct net_device *dev)
2150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002151{
2152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002153 hdd_context_t *pHddCtx = NULL;
2154 hdd_scaninfo_t *pScanInfo = NULL;
2155 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302156 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002157
2158 ENTER();
2159
2160 if (NULL == pAdapter)
2161 {
2162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002163 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 return -ENODEV;
2165 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002166
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2168 status = wlan_hdd_validate_context(pHddCtx);
2169
2170 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2173 "%s: HDD context is not valid", __func__);
2174 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002175 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002176
2177 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2178 if (NULL == staAdapter)
2179 {
2180 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2181 if (NULL == staAdapter)
2182 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002184 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002185 return -ENODEV;
2186 }
2187 }
2188
2189 pScanInfo = &pHddCtx->scan_info;
2190
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2192 __func__,pAdapter->device_mode);
2193
Jeff Johnsone7245742012-09-05 17:12:55 -07002194 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2195 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002196 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002197 hdd_abort_mac_scan(staAdapter->pHddCtx);
2198 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002199 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2201 if (!status)
2202 {
2203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002204 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002205 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002206 VOS_ASSERT(pScanInfo->mScanPending);
2207 return 0;
2208 }
2209 }
2210
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002213 )
2214 {
2215 beacon_data_t *old;
2216
2217 old = pAdapter->sessionCtx.ap.beacon;
2218
2219 if (!old)
2220 return -ENOENT;
2221
Jeff Johnson295189b2012-06-20 16:38:30 -07002222 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002223
2224 mutex_lock(&pHddCtx->sap_lock);
2225 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2226 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002227 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 {
2229 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2230
2231 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2232
2233 if (!VOS_IS_STATUS_SUCCESS(status))
2234 {
2235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2236 ("ERROR: HDD vos wait for single_event failed!!\n"));
2237 VOS_ASSERT(0);
2238 }
2239 }
2240 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2241 }
2242 mutex_unlock(&pHddCtx->sap_lock);
2243
2244 if(status != VOS_STATUS_SUCCESS)
2245 {
2246 hddLog(VOS_TRACE_LEVEL_FATAL,
2247 "%s:Error!!! Stopping the BSS\n",__func__);
2248 return -EINVAL;
2249 }
2250
Jeff Johnson4416a782013-03-25 14:17:50 -07002251 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002252 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2253 ==eHAL_STATUS_FAILURE)
2254 {
2255 hddLog(LOGE,
2256 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2257 }
2258
Jeff Johnson4416a782013-03-25 14:17:50 -07002259 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2261 eANI_BOOLEAN_FALSE) )
2262 {
2263 hddLog(LOGE,
2264 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2265 }
2266
2267 // Reset WNI_CFG_PROBE_RSP Flags
2268 wlan_hdd_reset_prob_rspies(pAdapter);
2269
2270 pAdapter->sessionCtx.ap.beacon = NULL;
2271 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002272#ifdef WLAN_FEATURE_P2P_DEBUG
2273 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2274 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2275 {
2276 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2277 "GO got removed");
2278 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2279 }
2280#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 }
2282 EXIT();
2283 return status;
2284}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002285
2286#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2287
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302288static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2289 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002290 struct cfg80211_ap_settings *params)
2291{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302292 hdd_adapter_t *pAdapter;
2293 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302294 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002295
2296 ENTER();
2297
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 "%s: Device is Null", __func__);
2302 return -ENODEV;
2303 }
2304
2305 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2306 if (NULL == pAdapter)
2307 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302309 "%s: HDD adapter is Null", __func__);
2310 return -ENODEV;
2311 }
2312
2313 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2314 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302316 "%s: HDD adapter magic is invalid", __func__);
2317 return -ENODEV;
2318 }
2319
2320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302321 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302322
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302323 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302324 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2326 "%s: HDD context is not valid", __func__);
2327 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302328 }
2329
2330 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2331 __func__, pAdapter->device_mode);
2332
2333 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002334 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002335 )
2336 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302337 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002338
2339 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302340
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002341 if (old)
2342 return -EALREADY;
2343
2344 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2345
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302346 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002347 {
2348 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302349 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002350 return -EINVAL;
2351 }
2352 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2354 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2355#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002356 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2357 params->ssid_len, params->hidden_ssid);
2358 }
2359
2360 EXIT();
2361 return status;
2362}
2363
2364
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302365static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002366 struct net_device *dev,
2367 struct cfg80211_beacon_data *params)
2368{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302370 hdd_context_t *pHddCtx;
2371 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002372
2373 ENTER();
2374
2375 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2376 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302377
2378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2379 status = wlan_hdd_validate_context(pHddCtx);
2380
2381 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002382 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2384 "%s: HDD context is not valid", __func__);
2385 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002386 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002387
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302388 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302390 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002391 {
2392 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302393
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002394 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302395
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396 if (!old)
2397 return -ENOENT;
2398
2399 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2400
2401 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302402 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002403 "%s: Error!!! Allocating the new beacon\n",__func__);
2404 return -EINVAL;
2405 }
2406
2407 pAdapter->sessionCtx.ap.beacon = new;
2408
2409 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2410 }
2411
2412 EXIT();
2413 return status;
2414}
2415
2416#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2417
Jeff Johnson295189b2012-06-20 16:38:30 -07002418
2419static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2420 struct net_device *dev,
2421 struct bss_parameters *params)
2422{
2423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2424
2425 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302426
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2428 __func__,pAdapter->device_mode);
2429
2430 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302432 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002433 {
2434 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2435 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 {
2438 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 }
2441
2442 EXIT();
2443 return 0;
2444}
2445
2446/*
2447 * FUNCTION: wlan_hdd_cfg80211_change_iface
2448 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2449 */
2450int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2451 struct net_device *ndev,
2452 enum nl80211_iftype type,
2453 u32 *flags,
2454 struct vif_params *params
2455 )
2456{
2457 struct wireless_dev *wdev;
2458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2459 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002460 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 tCsrRoamProfile *pRoamProfile = NULL;
2462 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302463 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002464 eMib_dot11DesiredBssType connectedBssType;
2465 VOS_STATUS status;
2466
2467 ENTER();
2468
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302469 status = wlan_hdd_validate_context(pHddCtx);
2470
2471 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002472 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "%s: HDD context is not valid", __func__);
2475 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 }
2477
2478 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2479 __func__, pAdapter->device_mode);
2480
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302481 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002482 wdev = ndev->ieee80211_ptr;
2483
2484#ifdef WLAN_BTAMP_FEATURE
2485 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2486 (NL80211_IFTYPE_ADHOC == type)||
2487 (NL80211_IFTYPE_AP == type)||
2488 (NL80211_IFTYPE_P2P_GO == type))
2489 {
2490 pHddCtx->isAmpAllowed = VOS_FALSE;
2491 // stop AMP traffic
2492 status = WLANBAP_StopAmp();
2493 if(VOS_STATUS_SUCCESS != status )
2494 {
2495 pHddCtx->isAmpAllowed = VOS_TRUE;
2496 hddLog(VOS_TRACE_LEVEL_FATAL,
2497 "%s: Failed to stop AMP", __func__);
2498 return -EINVAL;
2499 }
2500 }
2501#endif //WLAN_BTAMP_FEATURE
2502 /* Reset the current device mode bit mask*/
2503 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2504
2505 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002507 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002508 )
2509 {
2510 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2511 pRoamProfile = &pWextState->roamProfile;
2512 LastBSSType = pRoamProfile->BSSType;
2513
2514 switch (type)
2515 {
2516 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 hddLog(VOS_TRACE_LEVEL_INFO,
2519 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2520 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002521#ifdef WLAN_FEATURE_11AC
2522 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2523 {
2524 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2525 }
2526#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302527 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002528 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002530 //Check for sub-string p2p to confirm its a p2p interface
2531 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302532 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002533 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2534 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2535 }
2536 else
2537 {
2538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002539 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 break;
2542 case NL80211_IFTYPE_ADHOC:
2543 hddLog(VOS_TRACE_LEVEL_INFO,
2544 "%s: setting interface Type to ADHOC", __func__);
2545 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2546 pRoamProfile->phyMode =
2547 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002548 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 wdev->iftype = type;
2550 break;
2551
2552 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 {
2555 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2556 "%s: setting interface Type to %s", __func__,
2557 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2558
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002559 //Cancel any remain on channel for GO mode
2560 if (NL80211_IFTYPE_P2P_GO == type)
2561 {
2562 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2563 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002564 if (NL80211_IFTYPE_AP == type)
2565 {
2566 /* As Loading WLAN Driver one interface being created for p2p device
2567 * address. This will take one HW STA and the max number of clients
2568 * that can connect to softAP will be reduced by one. so while changing
2569 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2570 * interface as it is not required in SoftAP mode.
2571 */
2572
2573 // Get P2P Adapter
2574 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2575
2576 if (pP2pAdapter)
2577 {
2578 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2579 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2580 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2581 }
2582 }
2583
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 //De-init the adapter.
2585 hdd_stop_adapter( pHddCtx, pAdapter );
2586 hdd_deinit_adapter( pHddCtx, pAdapter );
2587 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2589 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002590
2591 //Disable BMPS and IMPS if enabled
2592 //before starting Go
2593 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302595 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002596 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2597 {
2598 //Fail to Exit BMPS
2599 VOS_ASSERT(0);
2600 }
2601 }
2602
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002603 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2604 (pConfig->apRandomBssidEnabled))
2605 {
2606 /* To meet Android requirements create a randomized
2607 MAC address of the form 02:1A:11:Fx:xx:xx */
2608 get_random_bytes(&ndev->dev_addr[3], 3);
2609 ndev->dev_addr[0] = 0x02;
2610 ndev->dev_addr[1] = 0x1A;
2611 ndev->dev_addr[2] = 0x11;
2612 ndev->dev_addr[3] |= 0xF0;
2613 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2614 VOS_MAC_ADDR_SIZE);
2615 pr_info("wlan: Generated HotSpot BSSID "
2616 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2617 ndev->dev_addr[0],
2618 ndev->dev_addr[1],
2619 ndev->dev_addr[2],
2620 ndev->dev_addr[3],
2621 ndev->dev_addr[4],
2622 ndev->dev_addr[5]);
2623 }
2624
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 hdd_set_ap_ops( pAdapter->dev );
2626
2627 status = hdd_init_ap_mode(pAdapter);
2628 if(status != VOS_STATUS_SUCCESS)
2629 {
2630 hddLog(VOS_TRACE_LEVEL_FATAL,
2631 "%s: Error initializing the ap mode", __func__);
2632 return -EINVAL;
2633 }
2634 hdd_set_conparam(1);
2635
Jeff Johnson295189b2012-06-20 16:38:30 -07002636 /*interface type changed update in wiphy structure*/
2637 if(wdev)
2638 {
2639 wdev->iftype = type;
2640 pHddCtx->change_iface = type;
2641 }
2642 else
2643 {
2644 hddLog(VOS_TRACE_LEVEL_ERROR,
2645 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2646 return -EINVAL;
2647 }
2648 goto done;
2649 }
2650
2651 default:
2652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2653 __func__);
2654 return -EOPNOTSUPP;
2655 }
2656 }
2657 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002659 )
2660 {
2661 switch(type)
2662 {
2663 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002664 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002665 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002666 hdd_stop_adapter( pHddCtx, pAdapter );
2667 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002669 //Check for sub-string p2p to confirm its a p2p interface
2670 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002671 {
2672 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2673 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2674 }
2675 else
2676 {
2677 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002678 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 hdd_set_conparam(0);
2681 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2683 hdd_set_station_ops( pAdapter->dev );
2684 status = hdd_init_station_mode( pAdapter );
2685 if( VOS_STATUS_SUCCESS != status )
2686 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002687 /* In case of JB, for P2P-GO, only change interface will be called,
2688 * This is the right place to enable back bmps_imps()
2689 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302690 if (pHddCtx->hdd_wlan_suspended)
2691 {
2692 hdd_set_pwrparams(pHddCtx);
2693 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002694 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 goto done;
2696 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002698 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2700 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002701 goto done;
2702 default:
2703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2704 __func__);
2705 return -EOPNOTSUPP;
2706
2707 }
2708
2709 }
2710 else
2711 {
2712 return -EOPNOTSUPP;
2713 }
2714
2715
2716 if(pRoamProfile)
2717 {
2718 if ( LastBSSType != pRoamProfile->BSSType )
2719 {
2720 /*interface type changed update in wiphy structure*/
2721 wdev->iftype = type;
2722
2723 /*the BSS mode changed, We need to issue disconnect
2724 if connected or in IBSS disconnect state*/
2725 if ( hdd_connGetConnectedBssType(
2726 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2727 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2728 {
2729 /*need to issue a disconnect to CSR.*/
2730 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2731 if( eHAL_STATUS_SUCCESS ==
2732 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2733 pAdapter->sessionId,
2734 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2735 {
2736 wait_for_completion_interruptible_timeout(
2737 &pAdapter->disconnect_comp_var,
2738 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2739 }
2740 }
2741 }
2742 }
2743
2744done:
2745 /*set bitmask based on updated value*/
2746 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2747#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302748 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2750 {
2751 //we are ok to do AMP
2752 pHddCtx->isAmpAllowed = VOS_TRUE;
2753 }
2754#endif //WLAN_BTAMP_FEATURE
2755 EXIT();
2756 return 0;
2757}
2758
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002759#ifdef FEATURE_WLAN_TDLS
2760static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2761 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2762{
2763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2765 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002766 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002767
2768 ENTER();
2769
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302770 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002771 {
2772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "Invalid arguments");
2774 return -EINVAL;
2775 }
Hoonki Lee27511902013-03-14 18:19:06 -07002776
2777 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2778 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2781 "%s: TDLS mode is disabled OR not enabled in FW."
2782 MAC_ADDRESS_STR " Request declined.",
2783 __func__, MAC_ADDR_ARRAY(mac));
2784 return -ENOTSUPP;
2785 }
2786
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002787 if (pHddCtx->isLogpInProgress)
2788 {
2789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002791 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002792 return -EBUSY;
2793 }
2794
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002795 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2796
2797 if ( NULL == pTdlsPeer ) {
2798 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2799 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2800 __func__, MAC_ADDR_ARRAY(mac), update);
2801 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002802 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002803
2804 /* in add station, we accept existing valid staId if there is */
2805 if ((0 == update) &&
2806 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2807 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002808 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002809 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002810 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002811 " link_status %d. staId %d. add station ignored.",
2812 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2813 return 0;
2814 }
2815 /* in change station, we accept only when staId is valid */
2816 if ((1 == update) &&
2817 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2818 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2819 {
2820 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2821 "%s: " MAC_ADDRESS_STR
2822 " link status %d. staId %d. change station %s.",
2823 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2824 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2825 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002826 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002827
2828 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002829 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002830 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "%s: " MAC_ADDRESS_STR
2833 " TDLS setup is ongoing. Request declined.",
2834 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002835 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002836 }
2837
2838 /* first to check if we reached to maximum supported TDLS peer.
2839 TODO: for now, return -EPERM looks working fine,
2840 but need to check if any other errno fit into this category.*/
2841 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2842 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2844 "%s: " MAC_ADDRESS_STR
2845 " TDLS Max peer already connected. Request declined.",
2846 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002847 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848 }
2849 else
2850 {
2851 hddTdlsPeer_t *pTdlsPeer;
2852 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002853 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002854 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2857 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002858 return -EPERM;
2859 }
2860 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002861 if (0 == update)
2862 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002863
Jeff Johnsond75fe012013-04-06 10:53:06 -07002864 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302865 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002866 {
2867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2868 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002869 if(StaParams->htcap_present)
2870 {
2871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2872 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2873 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2874 "ht_capa->extended_capabilities: %0x",
2875 StaParams->HTCap.extendedHtCapInfo);
2876 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002877 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2878 "params->capability: %0x",StaParams->capability);
2879 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2880 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002881 if(StaParams->vhtcap_present)
2882 {
2883 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2884 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2885 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2886 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2887 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002888 {
2889 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002891 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2892 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2893 "[%d]: %x ", i, StaParams->supported_rates[i]);
2894 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002895 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302896 else if ((1 == update) && (NULL == StaParams))
2897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "%s : update is true, but staParams is NULL. Error!", __func__);
2900 return -EPERM;
2901 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002902
2903 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2904
2905 if (!update)
2906 {
2907 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2908 pAdapter->sessionId, mac);
2909 }
2910 else
2911 {
2912 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2913 pAdapter->sessionId, mac, StaParams);
2914 }
2915
2916 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2917 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2918
2919 if (!status)
2920 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002922 "%s: timeout waiting for tdls add station indication",
2923 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002924 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002925 }
2926 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2927 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002929 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002930 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002931 }
2932
2933 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002934
2935error:
2936 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2937 return -EPERM;
2938
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002939}
2940#endif
2941
Jeff Johnson295189b2012-06-20 16:38:30 -07002942static int wlan_hdd_change_station(struct wiphy *wiphy,
2943 struct net_device *dev,
2944 u8 *mac,
2945 struct station_parameters *params)
2946{
2947 VOS_STATUS status = VOS_STATUS_SUCCESS;
2948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302949 hdd_context_t *pHddCtx;
2950 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002951 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002952#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002953 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002954 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002955#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002956 ENTER();
2957
Gopichand Nakkala29149562013-05-10 21:43:41 +05302958 if ((NULL == pAdapter))
2959 {
2960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2961 "invalid adapter ");
2962 return -EINVAL;
2963 }
2964
2965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2966 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2967
2968 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2969 {
2970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2971 "invalid HDD state or HDD station context");
2972 return -EINVAL;
2973 }
2974
2975 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002976 {
2977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2978 "%s:LOGP in Progress. Ignore!!!", __func__);
2979 return -EAGAIN;
2980 }
2981
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2983
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002984 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2985 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002986 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002987 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302989 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002990 WLANTL_STA_AUTHENTICATED);
2991
Gopichand Nakkala29149562013-05-10 21:43:41 +05302992 if (status != VOS_STATUS_SUCCESS)
2993 {
2994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2995 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2996 return -EINVAL;
2997 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002998 }
2999 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003000 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3001 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303002#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003003 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3004 StaParams.capability = params->capability;
3005 StaParams.uapsd_queues = params->uapsd_queues;
3006 StaParams.max_sp = params->max_sp;
3007
3008 if (0 != params->ext_capab_len)
3009 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3010 sizeof(StaParams.extn_capability));
3011
3012 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003013 {
3014 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003015 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003016 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003017
3018 StaParams.supported_rates_len = params->supported_rates_len;
3019
3020 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3021 * The supported_rates array , for all the structures propogating till Add Sta
3022 * to the firmware has to be modified , if the supplicant (ieee80211) is
3023 * modified to send more rates.
3024 */
3025
3026 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3027 */
3028 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3029 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3030
3031 if (0 != StaParams.supported_rates_len) {
3032 int i = 0;
3033 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3034 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003036 "Supported Rates with Length %d", StaParams.supported_rates_len);
3037 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003039 "[%d]: %0x", i, StaParams.supported_rates[i]);
3040 }
3041
3042 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003043 {
3044 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003045 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003046 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003047
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003048 if (0 != params->ext_capab_len ) {
3049 /*Define A Macro : TODO Sunil*/
3050 if ((1<<4) & StaParams.extn_capability[3]) {
3051 isBufSta = 1;
3052 }
3053 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303054 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3055 params->max_sp, isBufSta);
3056 if (VOS_STATUS_SUCCESS != status) {
3057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3058 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3059 return -EINVAL;
3060 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003061 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3062
3063 if (VOS_STATUS_SUCCESS != status) {
3064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3065 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3066 return -EINVAL;
3067 }
3068 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003069#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303070 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003071 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 return status;
3073}
3074
3075/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 * FUNCTION: wlan_hdd_cfg80211_add_key
3077 * This function is used to initialize the key information
3078 */
3079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003080static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003081 struct net_device *ndev,
3082 u8 key_index, bool pairwise,
3083 const u8 *mac_addr,
3084 struct key_params *params
3085 )
3086#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003087static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 struct net_device *ndev,
3089 u8 key_index, const u8 *mac_addr,
3090 struct key_params *params
3091 )
3092#endif
3093{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 tCsrRoamSetKey setKey;
3096 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303097 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003098 v_U32_t roamId= 0xFF;
3099 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 hdd_hostapd_state_t *pHostapdState;
3101 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003102 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303103 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 ENTER();
3106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3108 status = wlan_hdd_validate_context(pHddCtx);
3109
3110 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: HDD context is not valid", __func__);
3114 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003115 }
3116
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3118 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 if (CSR_MAX_NUM_KEY <= key_index)
3121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 key_index);
3124
3125 return -EINVAL;
3126 }
3127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003128 if (CSR_MAX_KEY_LEN < params->key_len)
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3131 params->key_len);
3132
3133 return -EINVAL;
3134 }
3135
3136 hddLog(VOS_TRACE_LEVEL_INFO,
3137 "%s: called with key index = %d & key length %d",
3138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003139
3140 /*extract key idx, key len and key*/
3141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3142 setKey.keyId = key_index;
3143 setKey.keyLength = params->key_len;
3144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 {
3148 case WLAN_CIPHER_SUITE_WEP40:
3149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3150 break;
3151
3152 case WLAN_CIPHER_SUITE_WEP104:
3153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3154 break;
3155
3156 case WLAN_CIPHER_SUITE_TKIP:
3157 {
3158 u8 *pKey = &setKey.Key[0];
3159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3160
3161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003164
3165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 |--------------|----------|----------|
3168 <---16bytes---><--8bytes--><--8bytes-->
3169
3170 */
3171 /*Sme expects the 32 bytes key to be in the below order
3172
3173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 |--------------|----------|----------|
3176 <---16bytes---><--8bytes--><--8bytes-->
3177 */
3178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180
3181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187
3188 break;
3189 }
3190
3191 case WLAN_CIPHER_SUITE_CCMP:
3192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3193 break;
3194
3195#ifdef FEATURE_WLAN_WAPI
3196 case WLAN_CIPHER_SUITE_SMS4:
3197 {
3198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3200 params->key, params->key_len);
3201 return 0;
3202 }
3203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205#ifdef FEATURE_WLAN_CCX
3206 case WLAN_CIPHER_SUITE_KRK:
3207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3208 break;
3209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003210
3211#ifdef WLAN_FEATURE_11W
3212 case WLAN_CIPHER_SUITE_AES_CMAC:
3213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003215#endif
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 default:
3218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3219 __func__, params->cipher);
3220 return -EOPNOTSUPP;
3221 }
3222
3223 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3224 __func__, setKey.encType);
3225
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003226 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3228 (!pairwise)
3229#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003230 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003231#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003232 )
3233 {
3234 /* set group key*/
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s- %d: setting Broadcast key",
3237 __func__, __LINE__);
3238 setKey.keyDirection = eSIR_RX_ONLY;
3239 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3240 }
3241 else
3242 {
3243 /* set pairwise key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s- %d: setting pairwise key",
3246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_TX_RX;
3248 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3249 }
3250 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3251 {
3252 setKey.keyDirection = eSIR_TX_RX;
3253 /*Set the group key*/
3254 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3255 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003256
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003257 if ( 0 != status )
3258 {
3259 hddLog(VOS_TRACE_LEVEL_ERROR,
3260 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3261 return -EINVAL;
3262 }
3263 /*Save the keys here and call sme_RoamSetKey for setting
3264 the PTK after peer joins the IBSS network*/
3265 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3266 &setKey, sizeof(tCsrRoamSetKey));
3267 return status;
3268 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303269 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3270 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3271 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003272 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003273 if( pHostapdState->bssState == BSS_START )
3274 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3276
3277 if ( status != eHAL_STATUS_SUCCESS )
3278 {
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3280 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3281 __LINE__, status );
3282 }
3283 }
3284
3285 /* Saving WEP keys */
3286 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3287 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3288 {
3289 //Save the wep key in ap context. Issue setkey after the BSS is started.
3290 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3291 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3292 }
3293 else
3294 {
3295 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003296 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003297 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3298 }
3299 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003300 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3301 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003302 {
3303 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3304 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3305
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3307 if (!pairwise)
3308#else
3309 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3310#endif
3311 {
3312 /* set group key*/
3313 if (pHddStaCtx->roam_info.deferKeyComplete)
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3316 "%s- %d: Perform Set key Complete",
3317 __func__, __LINE__);
3318 hdd_PerformRoamSetKeyComplete(pAdapter);
3319 }
3320 }
3321
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3323
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003324 pWextState->roamProfile.Keys.defaultIndex = key_index;
3325
3326
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003327 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003328 params->key, params->key_len);
3329
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303330
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3332
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303333 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003334 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303335 __func__, setKey.peerMac[0], setKey.peerMac[1],
3336 setKey.peerMac[2], setKey.peerMac[3],
3337 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003338 setKey.keyDirection);
3339
3340 vos_status = wlan_hdd_check_ula_done(pAdapter);
3341
3342 if ( vos_status != VOS_STATUS_SUCCESS )
3343 {
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3345 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3346 __LINE__, vos_status );
3347
3348 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3349
3350 return -EINVAL;
3351
3352 }
3353
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003354#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303355 /* The supplicant may attempt to set the PTK once pre-authentication
3356 is done. Save the key in the UMAC and include it in the ADD BSS
3357 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003358 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303359 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003360 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303361 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3362 "%s: Update PreAuth Key success", __func__);
3363 return 0;
3364 }
3365 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3366 {
3367 hddLog(VOS_TRACE_LEVEL_ERROR,
3368 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303369 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003370 }
3371#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003372
3373 /* issue set key request to SME*/
3374 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3375 pAdapter->sessionId, &setKey, &roamId );
3376
3377 if ( 0 != status )
3378 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303379 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3381 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3382 return -EINVAL;
3383 }
3384
3385
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303386 /* in case of IBSS as there was no information available about WEP keys during
3387 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3390 !( ( IW_AUTH_KEY_MGMT_802_1X
3391 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003392 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3393 )
3394 &&
3395 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3396 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3397 )
3398 )
3399 {
3400 setKey.keyDirection = eSIR_RX_ONLY;
3401 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303403 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003404 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303405 __func__, setKey.peerMac[0], setKey.peerMac[1],
3406 setKey.peerMac[2], setKey.peerMac[3],
3407 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 setKey.keyDirection);
3409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303410 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 pAdapter->sessionId, &setKey, &roamId );
3412
3413 if ( 0 != status )
3414 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303415 hddLog(VOS_TRACE_LEVEL_ERROR,
3416 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 __func__, status);
3418 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3419 return -EINVAL;
3420 }
3421 }
3422 }
3423
3424 return 0;
3425}
3426
3427/*
3428 * FUNCTION: wlan_hdd_cfg80211_get_key
3429 * This function is used to get the key information
3430 */
3431#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303432static int wlan_hdd_cfg80211_get_key(
3433 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303435 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003436 const u8 *mac_addr, void *cookie,
3437 void (*callback)(void *cookie, struct key_params*)
3438 )
3439#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303440static int wlan_hdd_cfg80211_get_key(
3441 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003442 struct net_device *ndev,
3443 u8 key_index, const u8 *mac_addr, void *cookie,
3444 void (*callback)(void *cookie, struct key_params*)
3445 )
3446#endif
3447{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003449 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3450 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3451 struct key_params params;
3452
3453 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303454
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3456 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 memset(&params, 0, sizeof(params));
3459
3460 if (CSR_MAX_NUM_KEY <= key_index)
3461 {
3462 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003464
3465 switch(pRoamProfile->EncryptionType.encryptionType[0])
3466 {
3467 case eCSR_ENCRYPT_TYPE_NONE:
3468 params.cipher = IW_AUTH_CIPHER_NONE;
3469 break;
3470
3471 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3472 case eCSR_ENCRYPT_TYPE_WEP40:
3473 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3474 break;
3475
3476 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3477 case eCSR_ENCRYPT_TYPE_WEP104:
3478 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3479 break;
3480
3481 case eCSR_ENCRYPT_TYPE_TKIP:
3482 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3483 break;
3484
3485 case eCSR_ENCRYPT_TYPE_AES:
3486 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3487 break;
3488
3489 default:
3490 params.cipher = IW_AUTH_CIPHER_NONE;
3491 break;
3492 }
3493
3494 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3495 params.seq_len = 0;
3496 params.seq = NULL;
3497 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3498 callback(cookie, &params);
3499 return 0;
3500}
3501
3502/*
3503 * FUNCTION: wlan_hdd_cfg80211_del_key
3504 * This function is used to delete the key information
3505 */
3506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303507static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303509 u8 key_index,
3510 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 const u8 *mac_addr
3512 )
3513#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303514static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 struct net_device *ndev,
3516 u8 key_index,
3517 const u8 *mac_addr
3518 )
3519#endif
3520{
3521 int status = 0;
3522
3523 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 //it is observed that this is invalidating peer
3526 //key index whenever re-key is done. This is affecting data link.
3527 //It should be ok to ignore del_key.
3528#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3530 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003531 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3532 tCsrRoamSetKey setKey;
3533 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303534
Jeff Johnson295189b2012-06-20 16:38:30 -07003535 ENTER();
3536
3537 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3538 __func__,pAdapter->device_mode);
3539
3540 if (CSR_MAX_NUM_KEY <= key_index)
3541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 key_index);
3544
3545 return -EINVAL;
3546 }
3547
3548 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3549 setKey.keyId = key_index;
3550
3551 if (mac_addr)
3552 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3553 else
3554 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3555
3556 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3557
3558 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003559 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560 )
3561 {
3562
3563 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003564 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3565 if( pHostapdState->bssState == BSS_START)
3566 {
3567 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303568
Jeff Johnson295189b2012-06-20 16:38:30 -07003569 if ( status != eHAL_STATUS_SUCCESS )
3570 {
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3573 __LINE__, status );
3574 }
3575 }
3576 }
3577 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303578 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 )
3580 {
3581 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303583 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3584
3585 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303587 __func__, setKey.peerMac[0], setKey.peerMac[1],
3588 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303590 if(pAdapter->sessionCtx.station.conn_info.connState ==
3591 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303593 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 if ( 0 != status )
3597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303598 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 "%s: sme_RoamSetKey failure, returned %d",
3600 __func__, status);
3601 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3602 return -EINVAL;
3603 }
3604 }
3605 }
3606#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003607 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 return status;
3609}
3610
3611/*
3612 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3613 * This function is used to set the default tx key index
3614 */
3615#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3616static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3617 struct net_device *ndev,
3618 u8 key_index,
3619 bool unicast, bool multicast)
3620#else
3621static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3622 struct net_device *ndev,
3623 u8 key_index)
3624#endif
3625{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303627 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303628 hdd_wext_state_t *pWextState;
3629 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303630 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003631
3632 ENTER();
3633
Gopichand Nakkala29149562013-05-10 21:43:41 +05303634 if ((NULL == pAdapter))
3635 {
3636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3637 "invalid adapter");
3638 return -EINVAL;
3639 }
3640
3641 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3642 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3643
3644 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3645 {
3646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3647 "invalid Wext state or HDD context");
3648 return -EINVAL;
3649 }
3650
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3652 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303653
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 if (CSR_MAX_NUM_KEY <= key_index)
3655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 key_index);
3658
3659 return -EINVAL;
3660 }
3661
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3663 status = wlan_hdd_validate_context(pHddCtx);
3664
3665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3668 "%s: HDD context is not valid", __func__);
3669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303671
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003673 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303674 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303676 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003679 pWextState->roamProfile.EncryptionType.encryptionType[0])
3680 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303681 {
3682 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303684
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 tCsrRoamSetKey setKey;
3686 v_U32_t roamId= 0xFF;
3687 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688
3689 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 Keys->defaultIndex = (u8)key_index;
3693 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3694 setKey.keyId = key_index;
3695 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696
3697 vos_mem_copy(&setKey.Key[0],
3698 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303700
Gopichand Nakkala29149562013-05-10 21:43:41 +05303701 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303702
3703 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 &pHddStaCtx->conn_info.bssId[0],
3705 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706
Gopichand Nakkala29149562013-05-10 21:43:41 +05303707 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3708 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3709 eCSR_ENCRYPT_TYPE_WEP104)
3710 {
3711 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3712 even though ap is configured for WEP-40 encryption. In this canse the key length
3713 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3714 type(104) and switching encryption type to 40*/
3715 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3716 eCSR_ENCRYPT_TYPE_WEP40;
3717 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3718 eCSR_ENCRYPT_TYPE_WEP40;
3719 }
3720
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303725 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303727
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 if ( 0 != status )
3729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003732 status);
3733 return -EINVAL;
3734 }
3735 }
3736 }
3737
3738 /* In SoftAp mode setting key direction for default mode */
3739 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3740 {
3741 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3742 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3743 (eCSR_ENCRYPT_TYPE_AES !=
3744 pWextState->roamProfile.EncryptionType.encryptionType[0])
3745 )
3746 {
3747 /* Saving key direction for default key index to TX default */
3748 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3749 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3750 }
3751 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303752
Jeff Johnson295189b2012-06-20 16:38:30 -07003753 return status;
3754}
3755
Jeff Johnson295189b2012-06-20 16:38:30 -07003756/*
3757 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3758 * This function is used to inform the BSS details to nl80211 interface.
3759 */
3760static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3761 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3762{
3763 struct net_device *dev = pAdapter->dev;
3764 struct wireless_dev *wdev = dev->ieee80211_ptr;
3765 struct wiphy *wiphy = wdev->wiphy;
3766 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3767 int chan_no;
3768 int ie_length;
3769 const char *ie;
3770 unsigned int freq;
3771 struct ieee80211_channel *chan;
3772 int rssi = 0;
3773 struct cfg80211_bss *bss = NULL;
3774
3775 ENTER();
3776
3777 if( NULL == pBssDesc )
3778 {
3779 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3780 return bss;
3781 }
3782
3783 chan_no = pBssDesc->channelId;
3784 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3785 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3786
3787 if( NULL == ie )
3788 {
3789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3790 return bss;
3791 }
3792
3793#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3794 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3795 {
3796 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3797 }
3798 else
3799 {
3800 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3801 }
3802#else
3803 freq = ieee80211_channel_to_frequency(chan_no);
3804#endif
3805
3806 chan = __ieee80211_get_channel(wiphy, freq);
3807
3808 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3809 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3810 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3811 if (bss == NULL)
3812 {
3813 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3814
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303815 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3816 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003817 pBssDesc->capabilityInfo,
3818 pBssDesc->beaconInterval, ie, ie_length,
3819 rssi, GFP_KERNEL ));
3820}
3821 else
3822 {
3823 return bss;
3824 }
3825}
3826
3827
3828
3829/*
3830 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3831 * This function is used to inform the BSS details to nl80211 interface.
3832 */
3833struct cfg80211_bss*
3834wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3835 tSirBssDescription *bss_desc
3836 )
3837{
3838 /*
3839 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3840 already exists in bss data base of cfg80211 for that particular BSS ID.
3841 Using cfg80211_inform_bss_frame to update the bss entry instead of
3842 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3843 now there is no possibility to get the mgmt(probe response) frame from PE,
3844 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3845 cfg80211_inform_bss_frame.
3846 */
3847 struct net_device *dev = pAdapter->dev;
3848 struct wireless_dev *wdev = dev->ieee80211_ptr;
3849 struct wiphy *wiphy = wdev->wiphy;
3850 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003851#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3852 qcom_ie_age *qie_age = NULL;
3853 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3854#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 const char *ie =
3858 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3859 unsigned int freq;
3860 struct ieee80211_channel *chan;
3861 struct ieee80211_mgmt *mgmt =
3862 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3863 struct cfg80211_bss *bss_status = NULL;
3864 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3865 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003866#ifdef WLAN_OPEN_SOURCE
3867 struct timespec ts;
3868#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003869
3870 ENTER();
3871
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003872 if (!mgmt)
3873 return NULL;
3874
Jeff Johnson295189b2012-06-20 16:38:30 -07003875 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003876
3877#ifdef WLAN_OPEN_SOURCE
3878 /* Android does not want the timestamp from the frame.
3879 Instead it wants a monotonic increasing value */
3880 get_monotonic_boottime(&ts);
3881 mgmt->u.probe_resp.timestamp =
3882 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3883#else
3884 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3886 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003887
3888#endif
3889
Jeff Johnson295189b2012-06-20 16:38:30 -07003890 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3891 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003892
3893#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3894 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3895 /* Assuming this is the last IE, copy at the end */
3896 ie_length -=sizeof(qcom_ie_age);
3897 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3898 qie_age->element_id = QCOM_VENDOR_IE_ID;
3899 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3900 qie_age->oui_1 = QCOM_OUI1;
3901 qie_age->oui_2 = QCOM_OUI2;
3902 qie_age->oui_3 = QCOM_OUI3;
3903 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3904 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3905#endif
3906
Jeff Johnson295189b2012-06-20 16:38:30 -07003907 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303908 if (bss_desc->fProbeRsp)
3909 {
3910 mgmt->frame_control |=
3911 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3912 }
3913 else
3914 {
3915 mgmt->frame_control |=
3916 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003918
3919#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3922 {
3923 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303925 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003926 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3927
3928 {
3929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3930 }
3931 else
3932 {
3933 kfree(mgmt);
3934 return NULL;
3935 }
3936#else
3937 freq = ieee80211_channel_to_frequency(chan_no);
3938#endif
3939 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003940 /*when the band is changed on the fly using the GUI, three things are done
3941 * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function)
3942 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3943 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3944 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3945 * and discards the channels correponding to previous band and calls back with zero bss results.
3946 * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD
3947 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3948 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3949 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3950 * So drop the bss and continue to next bss.
3951 */
3952 if(chan == NULL)
3953 {
3954 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003955 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003956 return NULL;
3957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303959 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 * */
3961 if (( eConnectionState_Associated ==
3962 pAdapter->sessionCtx.station.conn_info.connState ) &&
3963 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3964 pAdapter->sessionCtx.station.conn_info.bssId,
3965 WNI_CFG_BSSID_LEN)))
3966 {
3967 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3968 rssi = (pAdapter->rssi * 100);
3969 }
3970 else
3971 {
3972 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3973 }
3974
3975 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3976 frame_len, rssi, GFP_KERNEL);
3977 kfree(mgmt);
3978 return bss_status;
3979}
3980
3981/*
3982 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3983 * This function is used to update the BSS data base of CFG8011
3984 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303985struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 tCsrRoamInfo *pRoamInfo
3987 )
3988{
3989 tCsrRoamConnectedProfile roamProfile;
3990 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3991 struct cfg80211_bss *bss = NULL;
3992
3993 ENTER();
3994
3995 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3996 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3997
3998 if (NULL != roamProfile.pBssDesc)
3999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304000 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004001 &roamProfile);
4002
4003 if (NULL == bss)
4004 {
4005 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4006 __func__);
4007 }
4008
4009 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4010 }
4011 else
4012 {
4013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4014 __func__);
4015 }
4016 return bss;
4017}
4018
4019/*
4020 * FUNCTION: wlan_hdd_cfg80211_update_bss
4021 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304022static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4023 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304025{
Jeff Johnson295189b2012-06-20 16:38:30 -07004026 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4027 tCsrScanResultInfo *pScanResult;
4028 eHalStatus status = 0;
4029 tScanResultHandle pResult;
4030 struct cfg80211_bss *bss_status = NULL;
4031
4032 ENTER();
4033
4034 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4035 {
4036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4037 return -EAGAIN;
4038 }
4039
4040 /*
4041 * start getting scan results and populate cgf80211 BSS database
4042 */
4043 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4044
4045 /* no scan results */
4046 if (NULL == pResult)
4047 {
4048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4049 return status;
4050 }
4051
4052 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4053
4054 while (pScanResult)
4055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 /*
4057 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4058 * entry already exists in bss data base of cfg80211 for that
4059 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4060 * bss entry instead of cfg80211_inform_bss, But this call expects
4061 * mgmt packet as input. As of now there is no possibility to get
4062 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 * ieee80211_mgmt(probe response) and passing to c
4064 * fg80211_inform_bss_frame.
4065 * */
4066
4067 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4068 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304069
Jeff Johnson295189b2012-06-20 16:38:30 -07004070
4071 if (NULL == bss_status)
4072 {
4073 hddLog(VOS_TRACE_LEVEL_INFO,
4074 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4075 }
4076 else
4077 {
4078 cfg80211_put_bss(bss_status);
4079 }
4080
4081 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4082 }
4083
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304084 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004085
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304086 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004087}
4088
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004089void
4090hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4091{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004093 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4094 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4095 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004096} /****** end hddPrintMacAddr() ******/
4097
4098void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004099hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304101 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004102 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4103 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4104 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4105 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004106} /****** end hddPrintPmkId() ******/
4107
4108//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4109//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4110
4111//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4112//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4113
4114#define dump_bssid(bssid) \
4115 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004116 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4117 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4118 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004119 }
4120
4121#define dump_pmkid(pMac, pmkid) \
4122 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004123 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4124 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4125 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004126 }
4127
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004128#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004129/*
4130 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4131 * This function is used to notify the supplicant of a new PMKSA candidate.
4132 */
4133int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304134 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004135 int index, bool preauth )
4136{
Jeff Johnsone7245742012-09-05 17:12:55 -07004137#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004139 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004140
4141 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004142 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143
4144 if( NULL == pRoamInfo )
4145 {
4146 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4147 return -EINVAL;
4148 }
4149
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4151 {
4152 dump_bssid(pRoamInfo->bssid);
4153 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004154 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004155 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004156#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004158}
4159#endif //FEATURE_WLAN_LFR
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161/*
4162 * FUNCTION: hdd_cfg80211_scan_done_callback
4163 * scanning callback function, called after finishing scan
4164 *
4165 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4168{
4169 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304170 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004172 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4173 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 struct cfg80211_scan_request *req = NULL;
4175 int ret = 0;
4176
4177 ENTER();
4178
4179 hddLog(VOS_TRACE_LEVEL_INFO,
4180 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 __func__, halHandle, pContext, (int) scanId, (int) status);
4183
4184 //Block on scan req completion variable. Can't wait forever though.
4185 ret = wait_for_completion_interruptible_timeout(
4186 &pScanInfo->scan_req_completion_event,
4187 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4188 if (!ret)
4189 {
4190 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004191 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 }
4193
4194 if(pScanInfo->mScanPending != VOS_TRUE)
4195 {
4196 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004197 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 }
4199
4200 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304201 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004202 {
4203 hddLog(VOS_TRACE_LEVEL_INFO,
4204 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304205 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 (int) scanId);
4207 }
4208
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304209 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 pAdapter);
4211
4212 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004214
4215
4216 /* If any client wait scan result through WEXT
4217 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004218 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 {
4220 /* The other scan request waiting for current scan finish
4221 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004222 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004224 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 }
4226 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004227 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 {
4229 struct net_device *dev = pAdapter->dev;
4230 union iwreq_data wrqu;
4231 int we_event;
4232 char *msg;
4233
4234 memset(&wrqu, '\0', sizeof(wrqu));
4235 we_event = SIOCGIWSCAN;
4236 msg = NULL;
4237 wireless_send_event(dev, we_event, &wrqu, msg);
4238 }
4239 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004240 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004241
4242 /* Get the Scan Req */
4243 req = pAdapter->request;
4244
4245 if (!req)
4246 {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004248 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004249 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 }
4251
4252 /*
4253 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304254 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004255 req->n_ssids = 0;
4256 req->n_channels = 0;
4257 req->ie = 0;
4258
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004260 /* Scan is no longer pending */
4261 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004262
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004263 /*
4264 * cfg80211_scan_done informing NL80211 about completion
4265 * of scanning
4266 */
4267 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004268 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
Jeff Johnsone7245742012-09-05 17:12:55 -07004270allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004271 /* release the wake lock at the end of the scan*/
4272 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004273
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004274 /* Acquire wakelock to handle the case where APP's tries to suspend
4275 * immediatly after the driver gets connect request(i.e after scan)
4276 * from supplicant, this result in app's is suspending and not able
4277 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004278 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004279
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004280#ifdef FEATURE_WLAN_TDLS
4281 wlan_hdd_tdls_scan_done_callback(pAdapter);
4282#endif
4283
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 EXIT();
4285 return 0;
4286}
4287
4288/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004289 * FUNCTION: hdd_isScanAllowed
4290 * Go through each adapter and check if scan allowed
4291 *
4292 */
4293v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4294{
4295 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4296 hdd_station_ctx_t *pHddStaCtx = NULL;
4297 hdd_adapter_t *pAdapter = NULL;
4298 VOS_STATUS status = 0;
4299 v_U8_t staId = 0;
4300 v_U8_t *staMac = NULL;
4301
4302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4303
4304 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4305 {
4306 pAdapter = pAdapterNode->pAdapter;
4307
4308 if( pAdapter )
4309 {
4310 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304311 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004312 __func__, pAdapter->device_mode);
4313 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4314 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4315 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4316 {
4317 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4318 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4319 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4320 {
4321 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304324 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004325 staMac[0], staMac[1], staMac[2],
4326 staMac[3], staMac[4], staMac[5]);
4327 return VOS_FALSE;
4328 }
4329 }
4330 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4331 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4332 {
4333 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004336 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4337 {
4338 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4339
4340 hddLog(VOS_TRACE_LEVEL_ERROR,
4341 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004343 staMac[0], staMac[1], staMac[2],
4344 staMac[3], staMac[4], staMac[5]);
4345 return VOS_FALSE;
4346 }
4347 }
4348 }
4349 }
4350 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4351 pAdapterNode = pNext;
4352 }
4353 hddLog(VOS_TRACE_LEVEL_INFO,
4354 "%s: Scan allowed", __func__);
4355 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304356}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004357
4358/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004359 * FUNCTION: wlan_hdd_cfg80211_scan
4360 * this scan respond to scan trigger and update cfg80211 scan database
4361 * later, scan dump command can be used to recieve scan results
4362 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004363int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4364#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4365 struct net_device *dev,
4366#endif
4367 struct cfg80211_scan_request *request)
4368{
4369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4370 struct net_device *dev = request->wdev->netdev;
4371#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4374 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304375 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 tCsrScanRequest scanRequest;
4377 tANI_U8 *channelList = NULL, i;
4378 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304379 int status;
4380 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004382
4383 ENTER();
4384
4385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4386 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304388 status = wlan_hdd_validate_context(pHddCtx);
4389
4390 if (0 != status)
4391 {
4392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4393 "%s: HDD context is not valid", __func__);
4394 return status;
4395 }
4396
4397 cfg_param = pHddCtx->cfg_ini;
4398 pScanInfo = &pHddCtx->scan_info;
4399
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004400 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004401 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004402 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004403 {
4404 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004405 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4406 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004407 return -EBUSY;
4408 }
4409
Jeff Johnson295189b2012-06-20 16:38:30 -07004410#ifdef WLAN_BTAMP_FEATURE
4411 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004412 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004413 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 "%s: No scanning when AMP is on", __func__);
4416 return -EOPNOTSUPP;
4417 }
4418#endif
4419 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 "%s: Not scanning on device_mode = %d",
4424 __func__, pAdapter->device_mode);
4425 return -EOPNOTSUPP;
4426 }
4427
4428 if (TRUE == pScanInfo->mScanPending)
4429 {
4430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004431 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004432 }
4433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304434 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004435 //Channel and action frame is pending
4436 //Otherwise Cancel Remain On Channel and allow Scan
4437 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004438 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004439 {
4440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4441 return -EBUSY;
4442 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004443#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004444 /* if tdls disagree scan right now, return immediately.
4445 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4446 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4447 */
4448 status = wlan_hdd_tdls_scan_callback (pAdapter,
4449 wiphy,
4450#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4451 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004452#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004453 request);
4454 if(status <= 0)
4455 {
4456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4457 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004458 }
4459#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004460
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4462 {
4463 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004464 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4468 {
4469 hddLog(VOS_TRACE_LEVEL_WARN,
4470 "%s: MAX TM Level Scan not allowed", __func__);
4471 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304472 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004473 }
4474 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4475
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004476 /* Check if scan is allowed at this point of time.
4477 */
4478 if (!hdd_isScanAllowed(pHddCtx))
4479 {
4480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4481 return -EBUSY;
4482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304483
Jeff Johnson295189b2012-06-20 16:38:30 -07004484 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4485
4486 if (NULL != request)
4487 {
4488 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304489 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004490
4491 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4492 * Becasue of this, driver is assuming that this is not wildcard scan and so
4493 * is not aging out the scan results.
4494 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004495 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 {
4497 request->n_ssids = 0;
4498 }
4499
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004500 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 {
4502 tCsrSSIDInfo *SsidInfo;
4503 int j;
4504 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4505 /* Allocate num_ssid tCsrSSIDInfo structure */
4506 SsidInfo = scanRequest.SSIDs.SSIDList =
4507 ( tCsrSSIDInfo *)vos_mem_malloc(
4508 request->n_ssids*sizeof(tCsrSSIDInfo));
4509
4510 if(NULL == scanRequest.SSIDs.SSIDList)
4511 {
4512 hddLog(VOS_TRACE_LEVEL_ERROR,
4513 "memory alloc failed SSIDInfo buffer");
4514 return -ENOMEM;
4515 }
4516
4517 /* copy all the ssid's and their length */
4518 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4519 {
4520 /* get the ssid length */
4521 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4522 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4523 SsidInfo->SSID.length);
4524 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4525 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4526 j, SsidInfo->SSID.ssId);
4527 }
4528 /* set the scan type to active */
4529 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4530 }
4531 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4532 {
4533 /* set the scan type to active */
4534 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4535 }
4536 else
4537 {
4538 /*Set the scan type to default type, in this case it is ACTIVE*/
4539 scanRequest.scanType = pScanInfo->scan_mode;
4540 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4543 }
4544 else
4545 {
4546 /* set the scan type to active */
4547 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4548 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4549
4550 /* set min and max channel time to zero */
4551 scanRequest.minChnTime = 0;
4552 scanRequest.maxChnTime = 0;
4553 }
4554
4555 /* set BSSType to default type */
4556 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4557
4558 /*TODO: scan the requested channels only*/
4559
4560 /*Right now scanning all the channels */
4561 if( request )
4562 {
4563 if( request->n_channels )
4564 {
4565 channelList = vos_mem_malloc( request->n_channels );
4566 if( NULL == channelList )
4567 {
4568 status = -ENOMEM;
4569 goto free_mem;
4570 }
4571
4572 for( i = 0 ; i < request->n_channels ; i++ )
4573 channelList[i] = request->channels[i]->hw_value;
4574 }
4575
4576 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4577 scanRequest.ChannelInfo.ChannelList = channelList;
4578
4579 /* set requestType to full scan */
4580 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581
4582 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004583 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304584 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004585 */
4586
4587 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588 * and in that case driver shoudnt flush scan results. If
4589 * driver flushes the scan results here and unfortunately if
4590 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004591 * fails which is not desired
4592 */
4593
4594 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4595 {
4596 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4597 pAdapter->sessionId );
4598 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004599
4600 if( request->ie_len )
4601 {
4602 /* save this for future association (join requires this) */
4603 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4604 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4605 pScanInfo->scanAddIE.length = request->ie_len;
4606
4607 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004608 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4609 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004610 )
4611 {
4612 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4613 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4614 }
4615
4616 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4617 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4618
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4620 request->ie_len);
4621 if (pP2pIe != NULL)
4622 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004623#ifdef WLAN_FEATURE_P2P_DEBUG
4624 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4625 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4626 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4627 {
4628 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4629 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4630 "Go nego completed to Connection is started");
4631 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4632 "for 8way Handshake");
4633 }
4634 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4635 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4636 {
4637 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4639 "Disconnected state to Connection is started");
4640 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4641 "for 4way Handshake");
4642 }
4643#endif
4644
Jeff Johnsone7245742012-09-05 17:12:55 -07004645 /* no_cck will be set during p2p find to disable 11b rates */
4646 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 hddLog(VOS_TRACE_LEVEL_INFO,
4649 "%s: This is a P2P Search", __func__);
4650 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004651
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4653 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004654 /* set requestType to P2P Discovery */
4655 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004656 }
4657
4658 /*
4659 Skip Dfs Channel in case of P2P Search
4660 if it is set in ini file
4661 */
4662 if(cfg_param->skipDfsChnlInP2pSearch)
4663 {
4664 scanRequest.skipDfsChnlInP2pSearch = 1;
4665 }
4666 else
4667 {
4668 scanRequest.skipDfsChnlInP2pSearch = 0;
4669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004670
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 }
4672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 }
4674 }
4675
4676 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4677
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004678 /* acquire the wakelock to avoid the apps suspend during the scan. To
4679 * address the following issues.
4680 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4681 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4682 * for long time, this result in apps running at full power for long time.
4683 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4684 * be stuck in full power because of resume BMPS
4685 */
4686 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004687
4688 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 pAdapter->sessionId, &scanRequest, &scanId,
4690 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004691
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 if (eHAL_STATUS_SUCCESS != status)
4693 {
4694 hddLog(VOS_TRACE_LEVEL_ERROR,
4695 "%s: sme_ScanRequest returned error %d", __func__, status);
4696 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004697 if(eHAL_STATUS_RESOURCES == status)
4698 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004699 hddLog(VOS_TRACE_LEVEL_INFO, "%s: HO is in progress.So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004700 status = -EBUSY;
4701 } else {
4702 status = -EIO;
4703 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004704 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 goto free_mem;
4706 }
4707
4708 pScanInfo->mScanPending = TRUE;
4709 pAdapter->request = request;
4710 pScanInfo->scanId = scanId;
4711
4712 complete(&pScanInfo->scan_req_completion_event);
4713
4714free_mem:
4715 if( scanRequest.SSIDs.SSIDList )
4716 {
4717 vos_mem_free(scanRequest.SSIDs.SSIDList);
4718 }
4719
4720 if( channelList )
4721 vos_mem_free( channelList );
4722
4723 EXIT();
4724
4725 return status;
4726}
4727
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004728
4729void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4730{
4731 v_U8_t iniDot11Mode =
4732 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4733 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4734
4735 switch ( iniDot11Mode )
4736 {
4737 case eHDD_DOT11_MODE_AUTO:
4738 case eHDD_DOT11_MODE_11ac:
4739 case eHDD_DOT11_MODE_11ac_ONLY:
4740#ifdef WLAN_FEATURE_11AC
4741 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4742#else
4743 hddDot11Mode = eHDD_DOT11_MODE_11n;
4744#endif
4745 break;
4746 case eHDD_DOT11_MODE_11n:
4747 case eHDD_DOT11_MODE_11n_ONLY:
4748 hddDot11Mode = eHDD_DOT11_MODE_11n;
4749 break;
4750 default:
4751 hddDot11Mode = iniDot11Mode;
4752 break;
4753 }
4754 /* This call decides required channel bonding mode */
4755 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4756 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4757 operationChannel);
4758}
4759
Jeff Johnson295189b2012-06-20 16:38:30 -07004760/*
4761 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304762 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304764int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004765 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004766{
4767 int status = 0;
4768 hdd_wext_state_t *pWextState;
4769 v_U32_t roamId;
4770 tCsrRoamProfile *pRoamProfile;
4771 eMib_dot11DesiredBssType connectedBssType;
4772 eCsrAuthType RSNAuthType;
4773
4774 ENTER();
4775
4776 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304777
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4779 {
4780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4781 return -EINVAL;
4782 }
4783
4784 pRoamProfile = &pWextState->roamProfile;
4785
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304786 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004788 int ret = 0;
4789 hdd_station_ctx_t *pHddStaCtx;
4790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4791 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4792
4793 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4794 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4795 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 {
4797 /* Issue disconnect to CSR */
4798 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304799 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4801 pAdapter->sessionId,
4802 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4803 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004804 ret = wait_for_completion_interruptible_timeout(
4805 &pAdapter->disconnect_comp_var,
4806 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4807 if (0 == ret)
4808 {
4809 VOS_ASSERT(0);
4810 }
4811 }
4812 }
4813 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4814 {
4815 ret = wait_for_completion_interruptible_timeout(
4816 &pAdapter->disconnect_comp_var,
4817 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4818 if (0 == ret)
4819 {
4820 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 }
4822 }
4823
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304824 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4826 {
4827 /*QoS not enabled in cfg file*/
4828 pRoamProfile->uapsd_mask = 0;
4829 }
4830 else
4831 {
4832 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304833 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4835 }
4836
4837 pRoamProfile->SSIDs.numOfSSIDs = 1;
4838 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4839 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4842 ssid, ssid_len);
4843
4844 if (bssid)
4845 {
4846 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4847 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4848 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304849 /* Save BSSID in seperate variable as well, as RoamProfile
4850 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 case of join failure we should send valid BSSID to supplicant
4852 */
4853 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4854 WNI_CFG_BSSID_LEN);
4855 }
4856
4857 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4858 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304859 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 /*set gen ie*/
4861 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4862 /*set auth*/
4863 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004865#ifdef FEATURE_WLAN_WAPI
4866 if (pAdapter->wapi_info.nWapiMode)
4867 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004868 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004869 switch (pAdapter->wapi_info.wapiAuthMode)
4870 {
4871 case WAPI_AUTH_MODE_PSK:
4872 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004873 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 pAdapter->wapi_info.wapiAuthMode);
4875 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4876 break;
4877 }
4878 case WAPI_AUTH_MODE_CERT:
4879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004880 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 pAdapter->wapi_info.wapiAuthMode);
4882 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4883 break;
4884 }
4885 } // End of switch
4886 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4887 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4888 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004889 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 pRoamProfile->AuthType.numEntries = 1;
4891 pRoamProfile->EncryptionType.numEntries = 1;
4892 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4893 pRoamProfile->mcEncryptionType.numEntries = 1;
4894 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4895 }
4896 }
4897#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304898#ifdef WLAN_FEATURE_GTK_OFFLOAD
4899 /* Initializing gtkOffloadRequestParams */
4900 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4901 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4902 {
4903 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4904 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4905 0, sizeof (tSirGtkOffloadParams));
4906 }
4907#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 pRoamProfile->csrPersona = pAdapter->device_mode;
4909
Jeff Johnson32d95a32012-09-10 13:15:23 -07004910 if( operatingChannel )
4911 {
4912 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4913 pRoamProfile->ChannelInfo.numOfChannels = 1;
4914 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004915 else
4916 {
4917 pRoamProfile->ChannelInfo.ChannelList = NULL;
4918 pRoamProfile->ChannelInfo.numOfChannels = 0;
4919 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004920 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4921 {
4922 hdd_select_cbmode(pAdapter,operatingChannel);
4923 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004924 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4925 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304926 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004927 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004928 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4929 */
4930 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4931 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4932 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304933
4934 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 pAdapter->sessionId, pRoamProfile, &roamId);
4936
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004937 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304938 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4939
4940 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4942 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4943 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304944 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004945 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304946 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004947
4948 pRoamProfile->ChannelInfo.ChannelList = NULL;
4949 pRoamProfile->ChannelInfo.numOfChannels = 0;
4950
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 }
4952 else
4953 {
4954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4955 return -EINVAL;
4956 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004957 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 return status;
4959}
4960
4961/*
4962 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4963 * This function is used to set the authentication type (OPEN/SHARED).
4964 *
4965 */
4966static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4967 enum nl80211_auth_type auth_type)
4968{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304969 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4971
4972 ENTER();
4973
4974 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304975 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304978 hddLog(VOS_TRACE_LEVEL_INFO,
4979 "%s: set authentication type to AUTOSWITCH", __func__);
4980 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4981 break;
4982
4983 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004984#ifdef WLAN_FEATURE_VOWIFI_11R
4985 case NL80211_AUTHTYPE_FT:
4986#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304987 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004988 "%s: set authentication type to OPEN", __func__);
4989 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4990 break;
4991
4992 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304993 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004994 "%s: set authentication type to SHARED", __func__);
4995 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4996 break;
4997#ifdef FEATURE_WLAN_CCX
4998 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304999 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005000 "%s: set authentication type to CCKM WPA", __func__);
5001 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5002 break;
5003#endif
5004
5005
5006 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007 hddLog(VOS_TRACE_LEVEL_ERROR,
5008 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 auth_type);
5010 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5011 return -EINVAL;
5012 }
5013
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 pHddStaCtx->conn_info.authType;
5016 return 0;
5017}
5018
5019/*
5020 * FUNCTION: wlan_hdd_set_akm_suite
5021 * This function is used to set the key mgmt type(PSK/8021x).
5022 *
5023 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305024static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005025 u32 key_mgmt
5026 )
5027{
5028 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5029 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305030
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 /*set key mgmt type*/
5032 switch(key_mgmt)
5033 {
5034 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305035#ifdef WLAN_FEATURE_VOWIFI_11R
5036 case WLAN_AKM_SUITE_FT_PSK:
5037#endif
5038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 __func__);
5040 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5041 break;
5042
5043 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305044#ifdef WLAN_FEATURE_VOWIFI_11R
5045 case WLAN_AKM_SUITE_FT_8021X:
5046#endif
5047 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005048 __func__);
5049 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5050 break;
5051#ifdef FEATURE_WLAN_CCX
5052#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5053#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5054 case WLAN_AKM_SUITE_CCKM:
5055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5056 __func__);
5057 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5058 break;
5059#endif
5060
5061 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 __func__, key_mgmt);
5064 return -EINVAL;
5065
5066 }
5067 return 0;
5068}
5069
5070/*
5071 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305072 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005073 * (NONE/WEP40/WEP104/TKIP/CCMP).
5074 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5076 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 bool ucast
5078 )
5079{
5080 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305081 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5083
5084 ENTER();
5085
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305086 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 __func__, cipher);
5090 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5091 }
5092 else
5093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 {
5098 case IW_AUTH_CIPHER_NONE:
5099 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5100 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305101
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305103 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305107 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 case WLAN_CIPHER_SUITE_TKIP:
5111 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5112 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 case WLAN_CIPHER_SUITE_CCMP:
5115 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5116 break;
5117#ifdef FEATURE_WLAN_WAPI
5118 case WLAN_CIPHER_SUITE_SMS4:
5119 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5120 break;
5121#endif
5122
5123#ifdef FEATURE_WLAN_CCX
5124 case WLAN_CIPHER_SUITE_KRK:
5125 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5126 break;
5127#endif
5128 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 __func__, cipher);
5131 return -EOPNOTSUPP;
5132 }
5133 }
5134
5135 if (ucast)
5136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 __func__, encryptionType);
5139 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5140 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 encryptionType;
5143 }
5144 else
5145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305146 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005147 __func__, encryptionType);
5148 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5149 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5150 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5151 }
5152
5153 return 0;
5154}
5155
5156
5157/*
5158 * FUNCTION: wlan_hdd_cfg80211_set_ie
5159 * This function is used to parse WPA/RSN IE's.
5160 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305161int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5162 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 size_t ie_len
5164 )
5165{
5166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5167 u8 *genie = ie;
5168 v_U16_t remLen = ie_len;
5169#ifdef FEATURE_WLAN_WAPI
5170 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5171 u16 *tmp;
5172 v_U16_t akmsuiteCount;
5173 int *akmlist;
5174#endif
5175 ENTER();
5176
5177 /* clear previous assocAddIE */
5178 pWextState->assocAddIE.length = 0;
5179 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5180
5181 while (remLen >= 2)
5182 {
5183 v_U16_t eLen = 0;
5184 v_U8_t elementId;
5185 elementId = *genie++;
5186 eLen = *genie++;
5187 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188
5189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305191
5192 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005195 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 -07005196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 "%s: Invalid WPA IE", __func__);
5199 return -EINVAL;
5200 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 {
5203 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305206
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5208 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005209 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5210 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 VOS_ASSERT(0);
5212 return -ENOMEM;
5213 }
5214 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5215 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5216 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305217
Jeff Johnson295189b2012-06-20 16:38:30 -07005218 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5219 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5220 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5221 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305222 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5223 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5225 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5226 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5227 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5228 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5229 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305230 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5231 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 /*Consider P2P IE, only for P2P Client */
5233 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5234 {
5235 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305236 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305238
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5240 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005241 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5242 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 VOS_ASSERT(0);
5244 return -ENOMEM;
5245 }
5246 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5247 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5248 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305249
Jeff Johnson295189b2012-06-20 16:38:30 -07005250 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5251 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5252 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005253#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305254 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5255 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005256 /*Consider WFD IE, only for P2P Client */
5257 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5258 {
5259 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305260 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005261 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5264 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005265 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5266 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 VOS_ASSERT(0);
5268 return -ENOMEM;
5269 }
5270 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5271 // WPS IE + P2P IE + WFD IE
5272 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5273 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305274
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5276 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5277 }
5278#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005279 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305280 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005281 HS20_OUI_TYPE_SIZE)) )
5282 {
5283 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305284 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005285 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005286
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005287 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5288 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005289 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5290 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005291 VOS_ASSERT(0);
5292 return -ENOMEM;
5293 }
5294 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5295 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005296
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005297 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5298 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5299 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300
Jeff Johnson295189b2012-06-20 16:38:30 -07005301 break;
5302 case DOT11F_EID_RSN:
5303 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5304 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5305 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5306 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5307 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5308 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005309 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5310 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305311 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005312 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305313 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005314 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305315
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005316 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5317 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005318 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5319 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005320 VOS_ASSERT(0);
5321 return -ENOMEM;
5322 }
5323 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5324 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305325
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005326 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5327 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5328 break;
5329 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005330#ifdef FEATURE_WLAN_WAPI
5331 case WLAN_EID_WAPI:
5332 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5333 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5334 pAdapter->wapi_info.nWapiMode);
5335 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305336 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 akmsuiteCount = WPA_GET_LE16(tmp);
5338 tmp = tmp + 1;
5339 akmlist = (int *)(tmp);
5340 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5341 {
5342 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5343 }
5344 else
5345 {
5346 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5347 VOS_ASSERT(0);
5348 return -EINVAL;
5349 }
5350
5351 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5352 {
5353 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005354 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305358 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005360 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5362 }
5363 break;
5364#endif
5365 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305366 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005368 /* when Unknown IE is received we should break and continue
5369 * to the next IE in the buffer instead we were returning
5370 * so changing this to break */
5371 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005372 }
5373 genie += eLen;
5374 remLen -= eLen;
5375 }
5376 EXIT();
5377 return 0;
5378}
5379
5380/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305381 * FUNCTION: hdd_isWPAIEPresent
5382 * Parse the received IE to find the WPA IE
5383 *
5384 */
5385static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5386{
5387 v_U8_t eLen = 0;
5388 v_U16_t remLen = ie_len;
5389 v_U8_t elementId = 0;
5390
5391 while (remLen >= 2)
5392 {
5393 elementId = *ie++;
5394 eLen = *ie++;
5395 remLen -= 2;
5396 if (eLen > remLen)
5397 {
5398 hddLog(VOS_TRACE_LEVEL_ERROR,
5399 "%s: IE length is wrong %d", __func__, eLen);
5400 return FALSE;
5401 }
5402 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5403 {
5404 /* OUI - 0x00 0X50 0XF2
5405 WPA Information Element - 0x01
5406 WPA version - 0x01*/
5407 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5408 return TRUE;
5409 }
5410 ie += eLen;
5411 remLen -= eLen;
5412 }
5413 return FALSE;
5414}
5415
5416/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 * parameters during connect operation.
5420 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305421int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 struct cfg80211_connect_params *req
5423 )
5424{
5425 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 ENTER();
5428
5429 /*set wpa version*/
5430 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5431
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305432 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 {
5434 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305436 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005437 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305438 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 * since p2p ie is also put in same buffer.
5440 * */
5441 {
5442 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5443 }
5444 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5445 {
5446 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5447 }
5448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305449
5450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 pWextState->wpaVersion);
5452
5453 /*set authentication type*/
5454 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5455
5456 if (0 > status)
5457 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305458 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 "%s: failed to set authentication type ", __func__);
5460 return status;
5461 }
5462
5463 /*set key mgmt type*/
5464 if (req->crypto.n_akm_suites)
5465 {
5466 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5467 if (0 > status)
5468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305469 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 __func__);
5471 return status;
5472 }
5473 }
5474
5475 /*set pairwise cipher type*/
5476 if (req->crypto.n_ciphers_pairwise)
5477 {
5478 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5479 req->crypto.ciphers_pairwise[0], true);
5480 if (0 > status)
5481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 "%s: failed to set unicast cipher type", __func__);
5484 return status;
5485 }
5486 }
5487 else
5488 {
5489 /*Reset previous cipher suite to none*/
5490 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5491 if (0 > status)
5492 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305493 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 "%s: failed to set unicast cipher type", __func__);
5495 return status;
5496 }
5497 }
5498
5499 /*set group cipher type*/
5500 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5501 false);
5502
5503 if (0 > status)
5504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 __func__);
5507 return status;
5508 }
5509
Chet Lanctot186b5732013-03-18 10:26:30 -07005510#ifdef WLAN_FEATURE_11W
5511 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5512#endif
5513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5515 if (req->ie_len)
5516 {
5517 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5518 if ( 0 > status)
5519 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 __func__);
5522 return status;
5523 }
5524 }
5525
5526 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 {
5529 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5530 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5531 )
5532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305533 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005537 __func__);
5538 return -EOPNOTSUPP;
5539 }
5540 else
5541 {
5542 u8 key_len = req->key_len;
5543 u8 key_idx = req->key_idx;
5544
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305545 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 && (CSR_MAX_NUM_KEY > key_idx)
5547 )
5548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305549 hddLog(VOS_TRACE_LEVEL_INFO,
5550 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 __func__, key_idx, key_len);
5552 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305555 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 (u8)key_len;
5557 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5558 }
5559 }
5560 }
5561 }
5562
5563 return status;
5564}
5565
5566/*
5567 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 * parameters during connect operation.
5570 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 struct net_device *ndev,
5573 struct cfg80211_connect_params *req
5574 )
5575{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305576 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5579 hdd_context_t *pHddCtx = NULL;
5580
5581 ENTER();
5582
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5585
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5587 status = wlan_hdd_validate_context(pHddCtx);
5588
5589 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5592 "%s: HDD context is not valid", __func__);
5593 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 }
5595
5596#ifdef WLAN_BTAMP_FEATURE
5597 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305598 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305600 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005602 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 }
5604#endif
5605 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305606 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005607
5608 if ( 0 > status)
5609 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 __func__);
5612 return status;
5613 }
5614
5615 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005616 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5618 (vos_concurrent_sessions_running()))
5619 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305620 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 }
5622
Mohit Khanna765234a2012-09-11 15:08:35 -07005623 if ( req->channel )
5624 {
5625 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5626 req->ssid_len, req->bssid,
5627 req->channel->hw_value);
5628 }
5629 else
5630 {
5631 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305632 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005634
5635 if (0 > status)
5636 {
5637 //ReEnable BMPS if disabled
5638 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5639 (NULL != pHddCtx))
5640 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305641 if (pHddCtx->hdd_wlan_suspended)
5642 {
5643 hdd_set_pwrparams(pHddCtx);
5644 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005645 //ReEnable Bmps and Imps back
5646 hdd_enable_bmps_imps(pHddCtx);
5647 }
5648
5649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5650 return status;
5651 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305652 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 EXIT();
5654 return status;
5655}
5656
5657
5658/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305659 * FUNCTION: wlan_hdd_disconnect
5660 * This function is used to issue a disconnect request to SME
5661 */
5662int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5663{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305664 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305665 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5667
5668 status = wlan_hdd_validate_context(pHddCtx);
5669
5670 if (0 != status)
5671 {
5672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5673 "%s: HDD context is not valid", __func__);
5674 return status;
5675 }
5676
5677 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305678 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305679 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305680
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305681 /*issue disconnect*/
5682 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5683 pAdapter->sessionId, reason);
5684
5685 if ( 0 != status )
5686 {
5687 hddLog(VOS_TRACE_LEVEL_ERROR,
5688 "%s csrRoamDisconnect failure, returned %d \n",
5689 __func__, (int)status );
5690 return -EINVAL;
5691 }
5692 wait_for_completion_interruptible_timeout(
5693 &pAdapter->disconnect_comp_var,
5694 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5695 /*stop tx queues*/
5696 netif_tx_disable(pAdapter->dev);
5697 netif_carrier_off(pAdapter->dev);
5698 return status;
5699}
5700
5701
5702/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 * FUNCTION: wlan_hdd_cfg80211_disconnect
5704 * This function is used to issue a disconnect request to SME
5705 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305706static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 struct net_device *dev,
5708 u16 reason
5709 )
5710{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305711 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5712 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305714 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005715 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005716 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305717#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005718 tANI_U8 staIdx;
5719#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305720
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305722
5723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 __func__,pAdapter->device_mode);
5725
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305726 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5727 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005728
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305729 status = wlan_hdd_validate_context(pHddCtx);
5730
5731 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5734 "%s: HDD context is not valid", __func__);
5735 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305737
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 if (NULL != pRoamProfile)
5739 {
5740 /*issue disconnect request to SME, if station is in connected state*/
5741 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305745 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 switch(reason)
5747 {
5748 case WLAN_REASON_MIC_FAILURE:
5749 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5750 break;
5751
5752 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5753 case WLAN_REASON_DISASSOC_AP_BUSY:
5754 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5755 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5756 break;
5757
5758 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5759 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5760 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5761 break;
5762
5763 case WLAN_REASON_DEAUTH_LEAVING:
5764 default:
5765 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5766 break;
5767 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305768 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5769 pScanInfo = &pHddCtx->scan_info;
5770 if (pScanInfo->mScanPending)
5771 {
5772 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5773 "Aborting Scan");
5774 hdd_abort_mac_scan(pHddCtx);
5775 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005776
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005777#ifdef FEATURE_WLAN_TDLS
5778 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005779 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005780 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005781 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5782 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005783 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005784 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005785 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005786 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005787 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005788 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005789 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005790 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005791 pAdapter->sessionId,
5792 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005793 }
5794 }
5795#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305796 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5797 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 {
5799 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305800 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 __func__, (int)status );
5802 return -EINVAL;
5803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005804 }
5805 }
5806 else
5807 {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5809 }
5810
5811 return status;
5812}
5813
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305814
Jeff Johnson295189b2012-06-20 16:38:30 -07005815/*
5816 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305817 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 * settings in IBSS mode.
5819 */
5820static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 struct cfg80211_ibss_params *params
5823 )
5824{
5825 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 ENTER();
5831
5832 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5833
5834 if (params->ie_len && ( NULL != params->ie) )
5835 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305836 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 {
5838 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5839 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5840 }
5841 else
5842 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005843 tDot11fIEWPA dot11WPAIE;
5844 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
5845
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005847 // Unpack the WPA IE
5848 //Skip past the EID byte and length byte - and four byte WiFi OUI
5849 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5850 &params->ie[2+4],
5851 params->ie[1] - 4,
5852 &dot11WPAIE);
5853 /*Extract the multicast cipher, the encType for unicast
5854 cipher for wpa-none is none*/
5855 encryptionType =
5856 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 }
5858 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5859
5860 if (0 > status)
5861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 __func__);
5864 return status;
5865 }
5866 }
5867
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305868 pWextState->roamProfile.AuthType.authType[0] =
5869 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5871
5872 if (params->privacy)
5873 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305874 /* Security enabled IBSS, At this time there is no information available
5875 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305877 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305879 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 *enable privacy bit in beacons */
5881
5882 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5883 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005884 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5885 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5887 pWextState->roamProfile.EncryptionType.numEntries = 1;
5888 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005889 return status;
5890}
5891
5892/*
5893 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305896static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 struct net_device *dev,
5898 struct cfg80211_ibss_params *params
5899 )
5900{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5903 tCsrRoamProfile *pRoamProfile;
5904 int status;
5905 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305906 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005907
5908 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909
5910 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5912
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305913 status = wlan_hdd_validate_context(pHddCtx);
5914
5915 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5918 "%s: HDD context is not valid", __func__);
5919 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 }
5921
5922 if (NULL == pWextState)
5923 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 __func__);
5926 return -EIO;
5927 }
5928
5929 pRoamProfile = &pWextState->roamProfile;
5930
5931 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 "%s Interface type is not set to IBSS \n", __func__);
5935 return -EINVAL;
5936 }
5937
5938 /* Set Channel */
5939 if (NULL != params->channel)
5940 {
5941 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005942 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5943 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5944 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5945 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005946
5947 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305948 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 ieee80211_frequency_to_channel(params->channel->center_freq);
5950
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005951
5952 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5953 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5956 __func__);
5957 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005959
5960 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005962 if (channelNum == validChan[indx])
5963 {
5964 break;
5965 }
5966 }
5967 if (indx >= numChans)
5968 {
5969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 __func__, channelNum);
5971 return -EINVAL;
5972 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005973 /* Set the Operational Channel */
5974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5975 channelNum);
5976 pRoamProfile->ChannelInfo.numOfChannels = 1;
5977 pHddStaCtx->conn_info.operationChannel = channelNum;
5978 pRoamProfile->ChannelInfo.ChannelList =
5979 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 }
5981
5982 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305983 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 if (status < 0)
5985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 __func__);
5988 return status;
5989 }
5990
5991 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305992 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005993 params->ssid_len, params->bssid,
5994 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005995
5996 if (0 > status)
5997 {
5998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5999 return status;
6000 }
6001
6002 return 0;
6003}
6004
6005/*
6006 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 struct net_device *dev
6011 )
6012{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6015 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306016 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6017 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006018
6019 ENTER();
6020
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306021 status = wlan_hdd_validate_context(pHddCtx);
6022
6023 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6026 "%s: HDD context is not valid", __func__);
6027 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006028 }
6029
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6031 if (NULL == pWextState)
6032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 __func__);
6035 return -EIO;
6036 }
6037
6038 pRoamProfile = &pWextState->roamProfile;
6039
6040 /* Issue disconnect only if interface type is set to IBSS */
6041 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306043 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 __func__);
6045 return -EINVAL;
6046 }
6047
6048 /* Issue Disconnect request */
6049 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6050 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6051 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6052
6053 return 0;
6054}
6055
6056/*
6057 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6058 * This function is used to set the phy parameters
6059 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6060 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306061static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 u32 changed)
6063{
6064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6065 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306066 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006067
6068 ENTER();
6069
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306070 status = wlan_hdd_validate_context(pHddCtx);
6071
6072 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006073 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6075 "%s: HDD context is not valid", __func__);
6076 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006077 }
6078
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6080 {
6081 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6082 WNI_CFG_RTS_THRESHOLD_STAMAX :
6083 wiphy->rts_threshold;
6084
6085 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306086 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 hddLog(VOS_TRACE_LEVEL_ERROR,
6089 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 __func__, rts_threshold);
6091 return -EINVAL;
6092 }
6093
6094 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6095 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098 hddLog(VOS_TRACE_LEVEL_ERROR,
6099 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 __func__, rts_threshold);
6101 return -EIO;
6102 }
6103
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306104 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 rts_threshold);
6106 }
6107
6108 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6109 {
6110 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6111 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6112 wiphy->frag_threshold;
6113
6114 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306115 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306117 hddLog(VOS_TRACE_LEVEL_ERROR,
6118 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 frag_threshold);
6120 return -EINVAL;
6121 }
6122
6123 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6124 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306127 hddLog(VOS_TRACE_LEVEL_ERROR,
6128 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 __func__, frag_threshold);
6130 return -EIO;
6131 }
6132
6133 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6134 frag_threshold);
6135 }
6136
6137 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6138 || (changed & WIPHY_PARAM_RETRY_LONG))
6139 {
6140 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6141 wiphy->retry_short :
6142 wiphy->retry_long;
6143
6144 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6145 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6146 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 __func__, retry_value);
6149 return -EINVAL;
6150 }
6151
6152 if (changed & WIPHY_PARAM_RETRY_SHORT)
6153 {
6154 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6155 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306156 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306158 hddLog(VOS_TRACE_LEVEL_ERROR,
6159 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 __func__, retry_value);
6161 return -EIO;
6162 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306163 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 __func__, retry_value);
6165 }
6166 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6167 {
6168 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6169 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306170 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306172 hddLog(VOS_TRACE_LEVEL_ERROR,
6173 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 __func__, retry_value);
6175 return -EIO;
6176 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306177 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 __func__, retry_value);
6179 }
6180 }
6181
6182 return 0;
6183}
6184
6185/*
6186 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6187 * This function is used to set the txpower
6188 */
6189static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6190#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306191 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006192#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306193 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006194#endif
6195 int dbm)
6196{
6197 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306198 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6200 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306201 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006202
6203 ENTER();
6204
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306205 status = wlan_hdd_validate_context(pHddCtx);
6206
6207 if (0 != status)
6208 {
6209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6210 "%s: HDD context is not valid", __func__);
6211 return status;
6212 }
6213
6214 hHal = pHddCtx->hHal;
6215
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6217 dbm, ccmCfgSetCallback,
6218 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306220 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6222 return -EIO;
6223 }
6224
6225 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6226 dbm);
6227
6228 switch(type)
6229 {
6230 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6231 /* Fall through */
6232 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6233 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6234 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6236 __func__);
6237 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 }
6239 break;
6240 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 __func__);
6243 return -EOPNOTSUPP;
6244 break;
6245 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6247 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 return -EIO;
6249 }
6250
6251 return 0;
6252}
6253
6254/*
6255 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6256 * This function is used to read the txpower
6257 */
6258static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6259{
6260
6261 hdd_adapter_t *pAdapter;
6262 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306263 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006264
Jeff Johnsone7245742012-09-05 17:12:55 -07006265 ENTER();
6266
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306267 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006268
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306269 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006270 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6272 "%s: HDD context is not valid", __func__);
6273 *dbm = 0;
6274 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006275 }
6276
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6278 if (NULL == pAdapter)
6279 {
6280 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6281 return -ENOENT;
6282 }
6283
6284 wlan_hdd_get_classAstats(pAdapter);
6285 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6286
Jeff Johnsone7245742012-09-05 17:12:55 -07006287 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 return 0;
6289}
6290
6291static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6292 u8* mac, struct station_info *sinfo)
6293{
6294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6295 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6296 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6297 tANI_U8 rate_flags;
6298
6299 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6300 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006301
6302 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6303 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6304 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6305 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6306 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6307 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6308 tANI_U16 maxRate = 0;
6309 tANI_U16 myRate;
6310 tANI_U16 currentRate = 0;
6311 tANI_U8 maxSpeedMCS = 0;
6312 tANI_U8 maxMCSIdx = 0;
6313 tANI_U8 rateFlag = 1;
6314 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006315 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306316 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006317
Leo Chang6f8870f2013-03-26 18:11:36 -07006318#ifdef WLAN_FEATURE_11AC
6319 tANI_U32 vht_mcs_map;
6320 eDataRate11ACMaxMcs vhtMaxMcs;
6321#endif /* WLAN_FEATURE_11AC */
6322
Jeff Johnsone7245742012-09-05 17:12:55 -07006323 ENTER();
6324
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6326 (0 == ssidlen))
6327 {
6328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6329 " Invalid ssidlen, %d", __func__, ssidlen);
6330 /*To keep GUI happy*/
6331 return 0;
6332 }
6333
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306334 status = wlan_hdd_validate_context(pHddCtx);
6335
6336 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006337 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6339 "%s: HDD context is not valid", __func__);
6340 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006341 }
6342
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6344 sinfo->filled |= STATION_INFO_SIGNAL;
6345
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006346 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6348
6349 //convert to the UI units of 100kbps
6350 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6351
6352#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006353 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 -07006354 sinfo->signal,
6355 pCfg->reportMaxLinkSpeed,
6356 myRate,
6357 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006358 (int) pCfg->linkSpeedRssiMid,
6359 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006360 (int) rate_flags,
6361 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006362#endif //LINKSPEED_DEBUG_ENABLED
6363
6364 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6365 {
6366 // we do not want to necessarily report the current speed
6367 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6368 {
6369 // report the max possible speed
6370 rssidx = 0;
6371 }
6372 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6373 {
6374 // report the max possible speed with RSSI scaling
6375 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6376 {
6377 // report the max possible speed
6378 rssidx = 0;
6379 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006380 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 {
6382 // report middle speed
6383 rssidx = 1;
6384 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006385 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6386 {
6387 // report middle speed
6388 rssidx = 2;
6389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 else
6391 {
6392 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006393 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 }
6395 }
6396 else
6397 {
6398 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6399 hddLog(VOS_TRACE_LEVEL_ERROR,
6400 "%s: Invalid value for reportMaxLinkSpeed: %u",
6401 __func__, pCfg->reportMaxLinkSpeed);
6402 rssidx = 0;
6403 }
6404
6405 maxRate = 0;
6406
6407 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306408 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6409 OperationalRates, &ORLeng))
6410 {
6411 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6412 /*To keep GUI happy*/
6413 return 0;
6414 }
6415
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 for (i = 0; i < ORLeng; i++)
6417 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006418 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 {
6420 /* Validate Rate Set */
6421 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6422 {
6423 currentRate = supported_data_rate[j].supported_rate[rssidx];
6424 break;
6425 }
6426 }
6427 /* Update MAX rate */
6428 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6429 }
6430
6431 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306432 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6433 ExtendedRates, &ERLeng))
6434 {
6435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6436 /*To keep GUI happy*/
6437 return 0;
6438 }
6439
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 for (i = 0; i < ERLeng; i++)
6441 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006442 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
6444 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6445 {
6446 currentRate = supported_data_rate[j].supported_rate[rssidx];
6447 break;
6448 }
6449 }
6450 /* Update MAX rate */
6451 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 /* Get MCS Rate Set -- but only if we are connected at MCS
6454 rates or if we are always reporting max speed or if we have
6455 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006456 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306458 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6459 MCSRates, &MCSLeng))
6460 {
6461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6462 /*To keep GUI happy*/
6463 return 0;
6464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006466#ifdef WLAN_FEATURE_11AC
6467 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306468 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006470 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306471 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006472 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006474 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006476 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006478 maxMCSIdx = 7;
6479 }
6480 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6481 {
6482 maxMCSIdx = 8;
6483 }
6484 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6485 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306486 //VHT20 is supporting 0~8
6487 if (rate_flags & eHAL_TX_RATE_VHT20)
6488 maxMCSIdx = 8;
6489 else
6490 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006491 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306492
6493 if (rate_flags & eHAL_TX_RATE_VHT80)
6494 {
6495 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6496 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6497 }
6498 else if (rate_flags & eHAL_TX_RATE_VHT40)
6499 {
6500 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6501 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6502 }
6503 else if (rate_flags & eHAL_TX_RATE_VHT20)
6504 {
6505 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6506 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6507 }
6508
Leo Chang6f8870f2013-03-26 18:11:36 -07006509 maxSpeedMCS = 1;
6510 if (currentRate > maxRate)
6511 {
6512 maxRate = currentRate;
6513 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306514
Leo Chang6f8870f2013-03-26 18:11:36 -07006515 }
6516 else
6517#endif /* WLAN_FEATURE_11AC */
6518 {
6519 if (rate_flags & eHAL_TX_RATE_HT40)
6520 {
6521 rateFlag |= 1;
6522 }
6523 if (rate_flags & eHAL_TX_RATE_SGI)
6524 {
6525 rateFlag |= 2;
6526 }
6527
6528 for (i = 0; i < MCSLeng; i++)
6529 {
6530 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6531 for (j = 0; j < temp; j++)
6532 {
6533 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6534 {
6535 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6536 break;
6537 }
6538 }
6539 if ((j < temp) && (currentRate > maxRate))
6540 {
6541 maxRate = currentRate;
6542 maxSpeedMCS = 1;
6543 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6544 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 }
6546 }
6547 }
6548
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306549 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6550 {
6551 maxRate = myRate;
6552 maxSpeedMCS = 1;
6553 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6554 }
6555
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006557 if (((maxRate < myRate) && (0 == rssidx)) ||
6558 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 {
6560 maxRate = myRate;
6561 if (rate_flags & eHAL_TX_RATE_LEGACY)
6562 {
6563 maxSpeedMCS = 0;
6564 }
6565 else
6566 {
6567 maxSpeedMCS = 1;
6568 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6569 }
6570 }
6571
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306572 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 {
6574 sinfo->txrate.legacy = maxRate;
6575#ifdef LINKSPEED_DEBUG_ENABLED
6576 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6577#endif //LINKSPEED_DEBUG_ENABLED
6578 }
6579 else
6580 {
6581 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006582#ifdef WLAN_FEATURE_11AC
6583 sinfo->txrate.nss = 1;
6584 if (rate_flags & eHAL_TX_RATE_VHT80)
6585 {
6586 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306587 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006588 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306589 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006590 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306591 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6592 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6593 }
6594 else if (rate_flags & eHAL_TX_RATE_VHT20)
6595 {
6596 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6597 }
6598#endif /* WLAN_FEATURE_11AC */
6599 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6600 {
6601 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6602 if (rate_flags & eHAL_TX_RATE_HT40)
6603 {
6604 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6605 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 if (rate_flags & eHAL_TX_RATE_SGI)
6608 {
6609 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6610 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306611
Jeff Johnson295189b2012-06-20 16:38:30 -07006612#ifdef LINKSPEED_DEBUG_ENABLED
6613 pr_info("Reporting MCS rate %d flags %x\n",
6614 sinfo->txrate.mcs,
6615 sinfo->txrate.flags );
6616#endif //LINKSPEED_DEBUG_ENABLED
6617 }
6618 }
6619 else
6620 {
6621 // report current rate instead of max rate
6622
6623 if (rate_flags & eHAL_TX_RATE_LEGACY)
6624 {
6625 //provide to the UI in units of 100kbps
6626 sinfo->txrate.legacy = myRate;
6627#ifdef LINKSPEED_DEBUG_ENABLED
6628 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6629#endif //LINKSPEED_DEBUG_ENABLED
6630 }
6631 else
6632 {
6633 //must be MCS
6634 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006635#ifdef WLAN_FEATURE_11AC
6636 sinfo->txrate.nss = 1;
6637 if (rate_flags & eHAL_TX_RATE_VHT80)
6638 {
6639 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6640 }
6641 else
6642#endif /* WLAN_FEATURE_11AC */
6643 {
6644 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 if (rate_flags & eHAL_TX_RATE_SGI)
6647 {
6648 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6649 }
6650 if (rate_flags & eHAL_TX_RATE_HT40)
6651 {
6652 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6653 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006654#ifdef WLAN_FEATURE_11AC
6655 else if (rate_flags & eHAL_TX_RATE_VHT80)
6656 {
6657 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6658 }
6659#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006660#ifdef LINKSPEED_DEBUG_ENABLED
6661 pr_info("Reporting actual MCS rate %d flags %x\n",
6662 sinfo->txrate.mcs,
6663 sinfo->txrate.flags );
6664#endif //LINKSPEED_DEBUG_ENABLED
6665 }
6666 }
6667 sinfo->filled |= STATION_INFO_TX_BITRATE;
6668
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006669 sinfo->tx_packets =
6670 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6671 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6672 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6673 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6674
6675 sinfo->tx_retries =
6676 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6677 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6678 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6679 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6680
6681 sinfo->tx_failed =
6682 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6683 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6684 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6685 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6686
6687 sinfo->filled |=
6688 STATION_INFO_TX_PACKETS |
6689 STATION_INFO_TX_RETRIES |
6690 STATION_INFO_TX_FAILED;
6691
6692 EXIT();
6693 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006694}
6695
6696static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07006697 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07006698{
6699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306700 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306702 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006703
Jeff Johnsone7245742012-09-05 17:12:55 -07006704 ENTER();
6705
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 if (NULL == pAdapter)
6707 {
6708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6709 return -ENODEV;
6710 }
6711
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306712 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306713 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306714
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306715 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306716 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6718 "%s: HDD context is not valid", __func__);
6719 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306720 }
6721
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306722 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6723 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6724 (pHddCtx->cfg_ini->fhostArpOffload) &&
6725 (eConnectionState_Associated ==
6726 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6727 {
6728 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6729 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6730 {
6731 hddLog(VOS_TRACE_LEVEL_INFO,
6732 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6733 __func__, vos_status);
6734 }
6735 }
6736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 /**The get power cmd from the supplicant gets updated by the nl only
6738 *on successful execution of the function call
6739 *we are oppositely mapped w.r.t mode in the driver
6740 **/
6741 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6742
Jeff Johnsone7245742012-09-05 17:12:55 -07006743 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006744 if (VOS_STATUS_E_FAILURE == vos_status)
6745 {
6746 return -EINVAL;
6747 }
6748 return 0;
6749}
6750
6751
6752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6753static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6754 struct net_device *netdev,
6755 u8 key_index)
6756{
Jeff Johnsone7245742012-09-05 17:12:55 -07006757 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 return 0;
6759}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306760#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006761
6762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6763static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6764 struct net_device *dev,
6765 struct ieee80211_txq_params *params)
6766{
Jeff Johnsone7245742012-09-05 17:12:55 -07006767 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 return 0;
6769}
6770#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6771static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6772 struct ieee80211_txq_params *params)
6773{
Jeff Johnsone7245742012-09-05 17:12:55 -07006774 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 return 0;
6776}
6777#endif //LINUX_VERSION_CODE
6778
6779static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6780 struct net_device *dev, u8 *mac)
6781{
6782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306783 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006784 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306785 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006786 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006787
Jeff Johnsone7245742012-09-05 17:12:55 -07006788 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306789 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 return -EINVAL;
6793 }
6794
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306795 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6796 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006797
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306798 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6801 "%s: HDD context is not valid", __func__);
6802 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006803 }
6804
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 )
6808 {
6809 if( NULL == mac )
6810 {
6811 v_U16_t i;
6812 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6813 {
6814 if(pAdapter->aStaInfo[i].isUsed)
6815 {
6816 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6817 hddLog(VOS_TRACE_LEVEL_INFO,
6818 "%s: Delete STA with MAC::"
6819 "%02x:%02x:%02x:%02x:%02x:%02x",
6820 __func__,
6821 macAddr[0], macAddr[1], macAddr[2],
6822 macAddr[3], macAddr[4], macAddr[5]);
6823 hdd_softap_sta_deauth(pAdapter, macAddr);
6824 }
6825 }
6826 }
6827 else
6828 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006829
6830 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6831 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6832 {
6833 hddLog(VOS_TRACE_LEVEL_INFO,
6834 "%s: Skip this DEL STA as this is not used::"
6835 "%02x:%02x:%02x:%02x:%02x:%02x",
6836 __func__,
6837 mac[0], mac[1], mac[2],
6838 mac[3], mac[4], mac[5]);
6839 return -ENOENT;
6840 }
6841
6842 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6843 {
6844 hddLog(VOS_TRACE_LEVEL_INFO,
6845 "%s: Skip this DEL STA as deauth is in progress::"
6846 "%02x:%02x:%02x:%02x:%02x:%02x",
6847 __func__,
6848 mac[0], mac[1], mac[2],
6849 mac[3], mac[4], mac[5]);
6850 return -ENOENT;
6851 }
6852
6853 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6854
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 hddLog(VOS_TRACE_LEVEL_INFO,
6856 "%s: Delete STA with MAC::"
6857 "%02x:%02x:%02x:%02x:%02x:%02x",
6858 __func__,
6859 mac[0], mac[1], mac[2],
6860 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006861
6862 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6863 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6864 {
6865 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6866 hddLog(VOS_TRACE_LEVEL_INFO,
6867 "%s: STA removal failed for ::"
6868 "%02x:%02x:%02x:%02x:%02x:%02x",
6869 __func__,
6870 mac[0], mac[1], mac[2],
6871 mac[3], mac[4], mac[5]);
6872 return -ENOENT;
6873 }
6874
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 }
6876 }
6877
6878 EXIT();
6879
6880 return 0;
6881}
6882
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006883static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6884 struct net_device *dev, u8 *mac, struct station_parameters *params)
6885{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006886 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006887#ifdef FEATURE_WLAN_TDLS
6888 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006889 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006890 mask = params->sta_flags_mask;
6891
6892 set = params->sta_flags_set;
6893
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006894#ifdef WLAN_FEATURE_TDLS_DEBUG
6895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6896 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6897 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6898#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006899
6900 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6901 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006902 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006903 }
6904 }
6905#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006906 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006907}
6908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006909
6910#ifdef FEATURE_WLAN_LFR
6911static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006912 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006913{
6914#define MAX_PMKSAIDS_IN_CACHE 8
6915 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306916 static tANI_U32 i; // HDD Local Cache index
6917 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6919 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306921 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006922 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306923 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924
Jeff Johnsone7245742012-09-05 17:12:55 -07006925 ENTER();
6926
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306927 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306928 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006929 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006931 return -EINVAL;
6932 }
6933
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306934 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6935 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306937 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6940 "%s: HDD context is not valid", __func__);
6941 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006942 }
6943
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306944 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006945 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6946
6947 for (j = 0; j < i; j++)
6948 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306949 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006950 pmksa->bssid, WNI_CFG_BSSID_LEN))
6951 {
6952 /* BSSID matched previous entry. Overwrite it. */
6953 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306954 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006955 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306956 vos_mem_copy(PMKIDCache[j].PMKID,
6957 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006958 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306959 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006960 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006961 dump_bssid(pmksa->bssid);
6962 dump_pmkid(halHandle, pmksa->pmkid);
6963 break;
6964 }
6965 }
6966
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006967 /* Check we compared all entries,if then take the first slot now */
6968 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6969
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006970 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306971 {
6972 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6973 vos_mem_copy(PMKIDCache[i].BSSID,
6974 pmksa->bssid, ETHER_ADDR_LEN);
6975 vos_mem_copy(PMKIDCache[i].PMKID,
6976 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006977 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306978 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006979 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006980 dump_bssid(pmksa->bssid);
6981 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006983 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306984 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006985 }
6986
6987
6988 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006990 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006992 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006993 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306994 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6995 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006996 i );
6997 return 0;
6998}
6999
7000
7001static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007002 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007003{
Jeff Johnsone7245742012-09-05 17:12:55 -07007004 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007005 // TODO: Implement this later.
7006 return 0;
7007}
7008
7009static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7010{
Jeff Johnsone7245742012-09-05 17:12:55 -07007011 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007012 // TODO: Implement this later.
7013 return 0;
7014}
7015#endif
7016
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007017#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307018static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007019 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7020{
7021 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7022 hdd_station_ctx_t *pHddStaCtx;
7023
7024 if (NULL == pAdapter)
7025 {
7026 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7027 return -ENODEV;
7028 }
7029
7030 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7031
7032 // Added for debug on reception of Re-assoc Req.
7033 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307035 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007036 ftie->ie_len);
7037 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7038 }
7039
7040#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307041 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007042 ftie->ie_len);
7043#endif
7044
7045 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307046 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7047 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007048 ftie->ie_len);
7049 return 0;
7050}
7051#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007052
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307053#ifdef FEATURE_WLAN_SCAN_PNO
7054
7055void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7056 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7057{
7058 int ret;
7059 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7060 hdd_context_t *pHddCtx;
7061
7062 if (NULL == pAdapter)
7063 {
7064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7065 "%s: HDD adapter is Null", __func__);
7066 return ;
7067 }
7068
7069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7070 if (NULL == pHddCtx)
7071 {
7072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7073 "%s: HDD context is Null!!!", __func__);
7074 return ;
7075 }
7076
7077 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7078
7079 if (0 > ret)
7080 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7081
7082 cfg80211_sched_scan_results(pHddCtx->wiphy);
7083}
7084
7085/*
7086 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7087 * NL interface to enable PNO
7088 */
7089static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7090 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7091{
7092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7093 tpSirPNOScanReq pPnoRequest = NULL;
7094 hdd_context_t *pHddCtx;
7095 tHalHandle hHal;
7096 v_U32_t i, indx, num_ch;
7097 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7098 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7099 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7100 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307101 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307102
7103 if (NULL == pAdapter)
7104 {
7105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7106 "%s: HDD adapter is Null", __func__);
7107 return -ENODEV;
7108 }
7109
7110 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307111 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307112
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307113 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307114 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7116 "%s: HDD context is not valid", __func__);
7117 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307118 }
7119
7120 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7121 if (NULL == hHal)
7122 {
7123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7124 "%s: HAL context is Null!!!", __func__);
7125 return -EAGAIN;
7126 }
7127
7128 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7129 if (NULL == pPnoRequest)
7130 {
7131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7132 "%s: vos_mem_malloc failed", __func__);
7133 return -ENODEV;
7134 }
7135
7136 pPnoRequest->enable = 1; /*Enable PNO */
7137 pPnoRequest->ucNetworksCount = request->n_match_sets;
7138
7139 if (( !pPnoRequest->ucNetworksCount ) ||
7140 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7141 {
7142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7143 "Network input is not correct");
7144 goto error;
7145 }
7146
7147 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7148 {
7149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7150 "Incorrect number of channels");
7151 goto error;
7152 }
7153
7154 /* Framework provides one set of channels(all)
7155 * common for all saved profile */
7156 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7157 channels_allowed, &num_channels_allowed))
7158 {
7159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7160 "%s: failed to get valid channel list", __func__);
7161 goto error;
7162 }
7163 /* Checking each channel against allowed channel list */
7164 num_ch = 0;
7165 for (i = 0; i < request->n_channels; i++)
7166 {
7167 for (indx = 0; indx < num_channels_allowed; indx++)
7168 {
7169 if (request->channels[i]->hw_value == channels_allowed[indx])
7170 {
7171 valid_ch[num_ch++] = request->channels[i]->hw_value;
7172 break ;
7173 }
7174 }
7175 }
7176
7177 /* Filling per profile params */
7178 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7179 {
7180 pPnoRequest->aNetworks[i].ssId.length =
7181 request->match_sets[i].ssid.ssid_len;
7182
7183 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7184 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7185 {
7186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7187 "SSID Len %d is not correct for network %d",
7188 pPnoRequest->aNetworks[i].ssId.length, i);
7189 goto error;
7190 }
7191
7192 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7193 request->match_sets[i].ssid.ssid,
7194 request->match_sets[i].ssid.ssid_len);
7195 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7196 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7197 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7198
7199 /*Copying list of valid channel into request */
7200 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7201 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7202
7203 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7204 }
7205
7206 /* framework provides interval in ms */
7207 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7208 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7209 (request->interval)/1000;
7210 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7211 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7212
7213 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7214 pPnoRequest, pAdapter->sessionId,
7215 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7216 if (eHAL_STATUS_SUCCESS != status)
7217 {
7218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7219 "Failed to enable PNO");
7220 goto error;
7221 }
7222
7223error:
7224 vos_mem_free(pPnoRequest);
7225 return status;
7226}
7227
7228/*
7229 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7230 * NL interface to disable PNO
7231 */
7232static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7233 struct net_device *dev)
7234{
7235 eHalStatus status = eHAL_STATUS_FAILURE;
7236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7237 hdd_context_t *pHddCtx;
7238 tHalHandle hHal;
7239 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307240 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307241
7242 ENTER();
7243
7244 if (NULL == pAdapter)
7245 {
7246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7247 "%s: HDD adapter is Null", __func__);
7248 return -ENODEV;
7249 }
7250
7251 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307252 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307253
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307254 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307255 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7257 "%s: HDD context is not valid", __func__);
7258 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307259 }
7260
7261 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7262 if (NULL == hHal)
7263 {
7264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7265 "%s: HAL context is Null!!!", __func__);
7266 return -EAGAIN;
7267 }
7268
7269 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7270 if (NULL == pPnoRequest)
7271 {
7272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7273 "%s: vos_mem_malloc failed", __func__);
7274 return -ENODEV;
7275 }
7276
7277 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7278 pPnoRequest->enable = 0; /* Disable PNO */
7279 pPnoRequest->ucNetworksCount = 0;
7280
7281 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7282 pAdapter->sessionId,
7283 NULL, pAdapter);
7284 if (eHAL_STATUS_SUCCESS != status)
7285 {
7286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7287 "Failed to disabled PNO");
7288 }
7289
7290 vos_mem_free(pPnoRequest);
7291
7292 EXIT();
7293 return status;
7294}
7295
7296#endif /*FEATURE_WLAN_SCAN_PNO*/
7297
7298
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007299#ifdef FEATURE_WLAN_TDLS
7300static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7301 u8 *peer, u8 action_code, u8 dialog_token,
7302 u16 status_code, const u8 *buf, size_t len)
7303{
7304
7305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7306 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007307 u8 peerMac[6];
7308 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007309 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007310 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007311 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007312
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007313 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007316 "Invalid arguments");
7317 return -EINVAL;
7318 }
7319
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007320 if (pHddCtx->isLogpInProgress)
7321 {
7322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7323 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007324 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007325 return -EBUSY;
7326 }
7327
Hoonki Lee27511902013-03-14 18:19:06 -07007328 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007329 {
Hoonki Lee27511902013-03-14 18:19:06 -07007330 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7331 "%s: TDLS mode is disabled OR not enabled in FW."
7332 MAC_ADDRESS_STR " action %d declined.",
7333 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007334 return -ENOTSUPP;
7335 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007336
Hoonki Lee27511902013-03-14 18:19:06 -07007337 /* other than teardown frame, other mgmt frames are not sent if disabled */
7338 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7339 {
7340 /* if tdls_mode is disabled to respond to peer's request */
7341 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7342 {
7343 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7344 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007345 " TDLS mode is disabled. action %d declined.",
7346 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007347
7348 return -ENOTSUPP;
7349 }
7350 }
7351
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007352 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7353 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007354 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007355 {
7356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007357 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007358 " TDLS setup is ongoing. action %d declined.",
7359 __func__, MAC_ADDR_ARRAY(peer), action_code);
7360 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007361 }
7362 }
7363
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007364 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7365 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007366 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007367 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007368 {
7369 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7370 we return error code at 'add_station()'. Hence we have this
7371 check again in addtion to add_station().
7372 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007373 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007374 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7376 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007377 " TDLS Max peer already connected. action %d declined.",
7378 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007379 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007380 }
7381 else
7382 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007383 /* maximum reached. tweak to send error code to peer and return
7384 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007385 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7387 "%s: " MAC_ADDRESS_STR
7388 " TDLS Max peer already connected send response status %d",
7389 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007390 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007391 /* fall through to send setup resp with failure status
7392 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007393 }
7394 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007395 else
7396 {
7397 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007398 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007399 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007400 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007402 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7403 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007404 return -EPERM;
7405 }
7406 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007407 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007408 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007409
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007410#ifdef WLAN_FEATURE_TDLS_DEBUG
7411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007412 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7413 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7414 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007415#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007416
Hoonki Leea34dd892013-02-05 22:56:02 -08007417 /*Except teardown responder will not be used so just make 0*/
7418 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007419 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007420 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007421
7422 hddTdlsPeer_t *pTdlsPeer;
7423 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7424
7425 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7426 responder = pTdlsPeer->is_responder;
7427 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007428 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7430 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7431 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7432 dialog_token, status_code, len);
7433 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007434 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007435 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007436
Hoonki Lee14621352013-04-16 17:51:19 -07007437 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7438 (SIR_MAC_TDLS_DIS_RSP == action_code))
7439 {
7440 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7441 {
7442 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7443 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7444 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7445 }
7446 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7447 }
7448
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007449 /* make sure doesn't call send_mgmt() while it is pending */
7450 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7451 {
7452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7453 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7454 __func__, MAC_ADDR_ARRAY(peer), action_code);
7455 return -EBUSY;
7456 }
7457
7458 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007459 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7460
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007461 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007462 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007463
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007464 if (VOS_STATUS_SUCCESS != status)
7465 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7467 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007468 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007469 wlan_hdd_tdls_check_bmps(pAdapter);
7470 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007471 }
7472
Hoonki Leed37cbb32013-04-20 00:31:14 -07007473 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7474 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7475
7476 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007477 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7479 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7480 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007481 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007482 wlan_hdd_tdls_check_bmps(pAdapter);
7483 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007484 }
7485
Gopichand Nakkala05922802013-03-14 12:23:19 -07007486 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007487 {
7488 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007489 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007490 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007491
Hoonki Leea34dd892013-02-05 22:56:02 -08007492 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7493 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007494 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007495 }
7496 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7497 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007498 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007499 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007500
7501 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007502error:
7503 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7504 because we already know that this transaction will be failed,
7505 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7506 to be safe, do not change the state mahine.
7507 */
7508 if(max_sta_failed == 0 &&
7509 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7510 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7511 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007512}
7513
7514static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7515 u8 *peer, enum nl80211_tdls_operation oper)
7516{
7517 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7518 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307519 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307520#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7521 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307522 tANI_U8 staIdx;
7523#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007524#ifdef WLAN_FEATURE_TDLS_DEBUG
7525 const char *tdls_oper_str[]= {
7526 "NL80211_TDLS_DISCOVERY_REQ",
7527 "NL80211_TDLS_SETUP",
7528 "NL80211_TDLS_TEARDOWN",
7529 "NL80211_TDLS_ENABLE_LINK",
7530 "NL80211_TDLS_DISABLE_LINK",
7531 "NL80211_TDLS_UNKONW_OPER"};
7532#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007533 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007534
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307535 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007536 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007538 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007539 return -EINVAL;
7540 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007541
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307542 status = wlan_hdd_validate_context(pHddCtx);
7543
7544 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007545 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7547 "%s: HDD context is not valid", __func__);
7548 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007549 }
7550
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007551 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7552
7553 if ( NULL == pTdlsPeer ) {
7554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7555 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7556 return -EINVAL;
7557 }
7558
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007559#ifdef WLAN_FEATURE_TDLS_DEBUG
7560 if((int)oper > 4)
7561 oper = 5;
7562
7563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007564 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7565 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007566 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007567#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007568
7569 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007570 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007571 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007573 "TDLS Disabled in INI OR not enabled in FW. "
7574 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007575 return -ENOTSUPP;
7576 }
7577
7578 switch (oper) {
7579 case NL80211_TDLS_ENABLE_LINK:
7580 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007581 VOS_STATUS status;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307582 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007583
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007584 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7585 {
7586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7587 MAC_ADDRESS_STR " failed",
7588 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7589 return -EINVAL;
7590 }
7591
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007592 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007593 {
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307594 if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
7595 return -EINVAL;
7596 }
7597 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
7598
7599 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
7600 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
7601 /* Send TDLS peer UAPSD capabilities to the firmware and
7602 * register with the TL on after the response for this operation
7603 * is received .
7604 */
7605 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
7606 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
7607 if (status <= 0)
7608 {
7609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7610 "%s: Link Establish Request Faled Status %ld",
7611 __func__, status);
7612 return -EINVAL;
7613 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007614 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307615 /* Mark TDLS client Authenticated .*/
7616 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7617 pTdlsPeer->staId,
7618 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007619 if (VOS_STATUS_SUCCESS == status)
7620 {
Hoonki Lee14621352013-04-16 17:51:19 -07007621 if (pTdlsPeer->is_responder == 0)
7622 {
7623 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7624
7625 wlan_hdd_tdls_timer_restart(pAdapter,
7626 &pTdlsPeer->initiatorWaitTimeoutTimer,
7627 WAIT_TIME_TDLS_INITIATOR);
7628 /* suspend initiator TX until it receives direct packet from the
7629 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7630 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7631 &staId, NULL);
7632 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007633 wlan_hdd_tdls_increment_peer_count(pAdapter);
7634 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007635 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307636
7637 /* Update TL about the UAPSD masks , to route the packets to firmware */
7638 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7639 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VO )
7640 {
7641 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7642 pTdlsPeer->staId,
7643 WLANTL_AC_VO,
7644 7,
7645 7,
7646 0,
7647 0,
7648 WLANTL_BI_DIR );
7649
7650 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7651 }
7652
7653 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7654 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_VI )
7655 {
7656 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7657 pTdlsPeer->staId,
7658 WLANTL_AC_VI,
7659 5,
7660 5,
7661 0,
7662 0,
7663 WLANTL_BI_DIR );
7664
7665 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7666 }
7667
7668 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7669 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BK )
7670 {
7671 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7672 pTdlsPeer->staId,
7673 WLANTL_AC_BK,
7674 2,
7675 2,
7676 0,
7677 0,
7678 WLANTL_BI_DIR );
7679
7680 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7681 }
7682
7683 if ( TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta &&
7684 pHddCtx->cfg_ini->fTDLSUapsdMask & HDD_AC_BE )
7685 {
7686 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7687 pTdlsPeer->staId,
7688 WLANTL_AC_BE,
7689 3,
7690 3,
7691 0,
7692 0,
7693 WLANTL_BI_DIR );
7694
7695 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
7696 }
7697
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007698 }
7699
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007700 }
7701 break;
7702 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007703 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007704 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007705 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007706 long status;
7707
7708 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7709
Lee Hoonkic1262f22013-01-24 21:59:00 -08007710 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7711 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007712
7713 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7714 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7715 if (status <= 0)
7716 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007717 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7719 "%s: Del station failed status %ld",
7720 __func__, status);
7721 return -EPERM;
7722 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007723 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007724 }
7725 else
7726 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7728 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007729 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307730#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7731 if (pHddTdlsCtx->defer_link_lost_indication)
7732 {
7733 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7734 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7735 {
7736 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7737 if ( 0 != status)
7738 {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 "%s wlan_hdd_disconnect failure, returned %d \n",
7741 __func__, (int)status );
7742 return -EINVAL;
7743 }
7744 }
7745 }
7746#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007747 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007748 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007749 case NL80211_TDLS_TEARDOWN:
7750 case NL80211_TDLS_SETUP:
7751 case NL80211_TDLS_DISCOVERY_REQ:
7752 /* We don't support in-driver setup/teardown/discovery */
7753 return -ENOTSUPP;
7754 default:
7755 return -ENOTSUPP;
7756 }
7757 return 0;
7758}
Chilam NG571c65a2013-01-19 12:27:36 +05307759
7760int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7761 struct net_device *dev, u8 *peer)
7762{
7763 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7764 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7765
7766 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7767 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7768}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007769#endif
7770
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307771#ifdef WLAN_FEATURE_GTK_OFFLOAD
7772/*
7773 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7774 * Callback rountine called upon receiving response for
7775 * get offload info
7776 */
7777void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7778 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7779{
7780
7781 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7782
7783 ENTER();
7784
7785 if (NULL == pAdapter)
7786 {
7787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7788 "%s: HDD adapter is Null", __func__);
7789 return ;
7790 }
7791
7792 if (NULL == pGtkOffloadGetInfoRsp)
7793 {
7794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7795 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7796 return ;
7797 }
7798
7799 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7800 {
7801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7802 "%s: wlan Failed to get replay counter value",
7803 __func__);
7804 return ;
7805 }
7806
7807 /* Update replay counter to NL */
7808 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7809 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7810}
7811
7812/*
7813 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7814 * This function is used to offload GTK rekeying job to the firmware.
7815 */
7816int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7817 struct cfg80211_gtk_rekey_data *data)
7818{
7819 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7821 hdd_station_ctx_t *pHddStaCtx;
7822 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307823 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307824 tpSirGtkOffloadParams pGtkOffloadReqParams;
7825 eHalStatus status = eHAL_STATUS_FAILURE;
7826
7827 ENTER();
7828
7829 if (NULL == pAdapter)
7830 {
7831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7832 "%s: HDD adapter is Null", __func__);
7833 return -ENODEV;
7834 }
7835
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307836 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307837
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307838 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307839 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7841 "%s: HDD context is not valid", __func__);
7842 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307843 }
7844
7845 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7846 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7847 if (NULL == hHal)
7848 {
7849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7850 "%s: HAL context is Null!!!", __func__);
7851 return -EAGAIN;
7852 }
7853
7854 pGtkOffloadReqParams =
7855 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7856
7857 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7858 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7859 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7860 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7861 WNI_CFG_BSSID_LEN);
7862 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7863 sizeof (tANI_U64));
7864
7865 if (TRUE == pHddCtx->hdd_wlan_suspended)
7866 {
7867 /* if wlan is suspended, enable GTK offload directly from here */
7868 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7869 pAdapter->sessionId);
7870
7871 if (eHAL_STATUS_SUCCESS != status)
7872 {
7873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7874 "%s: sme_SetGTKOffload failed, returned %d",
7875 __func__, status);
7876 return status;
7877 }
7878 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7880 "%s: sme_SetGTKOffload successfull", __func__);
7881 }
7882 else
7883 {
7884 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7886 "%s: wlan not suspended GTKOffload request is stored",
7887 __func__);
7888 return eHAL_STATUS_SUCCESS;
7889 }
7890 return status;
7891}
7892#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7893
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307894/*
7895 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7896 * This function is used to set access control policy
7897 */
7898static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7899 struct net_device *dev, const struct cfg80211_acl_data *params)
7900{
7901 int i;
7902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7903 hdd_hostapd_state_t *pHostapdState;
7904 tsap_Config_t *pConfig;
7905 v_CONTEXT_t pVosContext = NULL;
7906 hdd_context_t *pHddCtx;
7907 int status;
7908
7909 ENTER();
7910
7911 if (NULL == pAdapter)
7912 {
7913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7914 "%s: HDD adapter is Null", __func__);
7915 return -ENODEV;
7916 }
7917
7918 if (NULL == params)
7919 {
7920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7921 "%s: params is Null", __func__);
7922 return -EINVAL;
7923 }
7924
7925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7926 status = wlan_hdd_validate_context(pHddCtx);
7927
7928 if (0 != status)
7929 {
7930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7931 "%s: HDD context is not valid", __func__);
7932 return status;
7933 }
7934
7935 pVosContext = pHddCtx->pvosContext;
7936 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7937
7938 if (NULL == pHostapdState)
7939 {
7940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7941 "%s: pHostapdState is Null", __func__);
7942 return -EINVAL;
7943 }
7944
7945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
7946 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
7947
7948 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
7949 {
7950 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
7951
7952 /* default value */
7953 pConfig->num_accept_mac = 0;
7954 pConfig->num_deny_mac = 0;
7955
7956 /**
7957 * access control policy
7958 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
7959 * listed in hostapd.deny file.
7960 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
7961 * listed in hostapd.accept file.
7962 */
7963 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
7964 {
7965 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
7966 }
7967 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
7968 {
7969 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7970 }
7971 else
7972 {
7973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7974 "%s:Acl Policy : %d is not supported",
7975 __func__, params->acl_policy);
7976 return -ENOTSUPP;
7977 }
7978
7979 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
7980 {
7981 pConfig->num_accept_mac = params->n_acl_entries;
7982 for (i = 0; i < params->n_acl_entries; i++)
7983 {
7984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7985 "** Add ACL MAC entry %i in WhiletList :"
7986 MAC_ADDRESS_STR, i,
7987 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
7988
7989 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
7990 sizeof(qcmacaddr));
7991 }
7992 }
7993 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
7994 {
7995 pConfig->num_deny_mac = params->n_acl_entries;
7996 for (i = 0; i < params->n_acl_entries; i++)
7997 {
7998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7999 "** Add ACL MAC entry %i in BlackList :"
8000 MAC_ADDRESS_STR, i,
8001 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8002
8003 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
8004 sizeof(qcmacaddr));
8005 }
8006 }
8007
8008 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
8009 {
8010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8011 "%s: SAP Set Mac Acl fail", __func__);
8012 return -EINVAL;
8013 }
8014 }
8015 else
8016 {
8017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8018 "%s: Invalid device_mode = %d",
8019 __func__, pAdapter->device_mode);
8020 return -EINVAL;
8021 }
8022
8023 return 0;
8024}
8025
Jeff Johnson295189b2012-06-20 16:38:30 -07008026/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308027static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07008028{
8029 .add_virtual_intf = wlan_hdd_add_virtual_intf,
8030 .del_virtual_intf = wlan_hdd_del_virtual_intf,
8031 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
8032 .change_station = wlan_hdd_change_station,
8033#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8034 .add_beacon = wlan_hdd_cfg80211_add_beacon,
8035 .del_beacon = wlan_hdd_cfg80211_del_beacon,
8036 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008037#else
8038 .start_ap = wlan_hdd_cfg80211_start_ap,
8039 .change_beacon = wlan_hdd_cfg80211_change_beacon,
8040 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07008041#endif
8042 .change_bss = wlan_hdd_cfg80211_change_bss,
8043 .add_key = wlan_hdd_cfg80211_add_key,
8044 .get_key = wlan_hdd_cfg80211_get_key,
8045 .del_key = wlan_hdd_cfg80211_del_key,
8046 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008047#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008048 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 .scan = wlan_hdd_cfg80211_scan,
8051 .connect = wlan_hdd_cfg80211_connect,
8052 .disconnect = wlan_hdd_cfg80211_disconnect,
8053 .join_ibss = wlan_hdd_cfg80211_join_ibss,
8054 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
8055 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
8056 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
8057 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
8059 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
8060 .mgmt_tx = wlan_hdd_action,
8061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8062 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
8063 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
8064 .set_txq_params = wlan_hdd_set_txq_params,
8065#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 .get_station = wlan_hdd_cfg80211_get_station,
8067 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
8068 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008069 .add_station = wlan_hdd_cfg80211_add_station,
8070#ifdef FEATURE_WLAN_LFR
8071 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
8072 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
8073 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
8074#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008075#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8076 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8077#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008078#ifdef FEATURE_WLAN_TDLS
8079 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8080 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8081#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308082#ifdef WLAN_FEATURE_GTK_OFFLOAD
8083 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8084#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308085#ifdef FEATURE_WLAN_SCAN_PNO
8086 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8087 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8088#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308089 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008090};
8091