blob: ade5155559cec4a9ef38c48349385678f7952dc0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Wilson Yangef657d32014-01-15 19:19:23 -08002 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303 *
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"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053087#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080088#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053089#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070090#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070091
92#define g_mode_rates_size (12)
93#define a_mode_rates_size (8)
94#define FREQ_BASE_80211G (2407)
95#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070096#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +053097#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -070098#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
99 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
100
101#define HDD2GHZCHAN(freq, chan, flag) { \
102 .band = IEEE80211_BAND_2GHZ, \
103 .center_freq = (freq), \
104 .hw_value = (chan),\
105 .flags = (flag), \
106 .max_antenna_gain = 0 ,\
107 .max_power = 30, \
108}
109
110#define HDD5GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_5GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
120{\
121 .bitrate = rate, \
122 .hw_value = rate_id, \
123 .flags = flag, \
124}
125
Lee Hoonkic1262f22013-01-24 21:59:00 -0800126#ifndef WLAN_FEATURE_TDLS_DEBUG
127#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
128#else
129#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
130#endif
131
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530132#ifdef WLAN_FEATURE_VOWIFI_11R
133#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
134#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
135#endif
136
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530137static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700138{
139 WLAN_CIPHER_SUITE_WEP40,
140 WLAN_CIPHER_SUITE_WEP104,
141 WLAN_CIPHER_SUITE_TKIP,
142#ifdef FEATURE_WLAN_CCX
143#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
144 WLAN_CIPHER_SUITE_KRK,
145 WLAN_CIPHER_SUITE_CCMP,
146#else
147 WLAN_CIPHER_SUITE_CCMP,
148#endif
149#ifdef FEATURE_WLAN_WAPI
150 WLAN_CIPHER_SUITE_SMS4,
151#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700152#ifdef WLAN_FEATURE_11W
153 WLAN_CIPHER_SUITE_AES_CMAC,
154#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700155};
156
157static inline int is_broadcast_ether_addr(const u8 *addr)
158{
159 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
160 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
161}
162
163static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530164{
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 HDD2GHZCHAN(2412, 1, 0) ,
166 HDD2GHZCHAN(2417, 2, 0) ,
167 HDD2GHZCHAN(2422, 3, 0) ,
168 HDD2GHZCHAN(2427, 4, 0) ,
169 HDD2GHZCHAN(2432, 5, 0) ,
170 HDD2GHZCHAN(2437, 6, 0) ,
171 HDD2GHZCHAN(2442, 7, 0) ,
172 HDD2GHZCHAN(2447, 8, 0) ,
173 HDD2GHZCHAN(2452, 9, 0) ,
174 HDD2GHZCHAN(2457, 10, 0) ,
175 HDD2GHZCHAN(2462, 11, 0) ,
176 HDD2GHZCHAN(2467, 12, 0) ,
177 HDD2GHZCHAN(2472, 13, 0) ,
178 HDD2GHZCHAN(2484, 14, 0) ,
179};
180
Jeff Johnson295189b2012-06-20 16:38:30 -0700181static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
182{
183 HDD2GHZCHAN(2412, 1, 0) ,
184 HDD2GHZCHAN(2437, 6, 0) ,
185 HDD2GHZCHAN(2462, 11, 0) ,
186};
Jeff Johnson295189b2012-06-20 16:38:30 -0700187
188static struct ieee80211_channel hdd_channels_5_GHZ[] =
189{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700190 HDD5GHZCHAN(4920, 240, 0) ,
191 HDD5GHZCHAN(4940, 244, 0) ,
192 HDD5GHZCHAN(4960, 248, 0) ,
193 HDD5GHZCHAN(4980, 252, 0) ,
194 HDD5GHZCHAN(5040, 208, 0) ,
195 HDD5GHZCHAN(5060, 212, 0) ,
196 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 HDD5GHZCHAN(5180, 36, 0) ,
198 HDD5GHZCHAN(5200, 40, 0) ,
199 HDD5GHZCHAN(5220, 44, 0) ,
200 HDD5GHZCHAN(5240, 48, 0) ,
201 HDD5GHZCHAN(5260, 52, 0) ,
202 HDD5GHZCHAN(5280, 56, 0) ,
203 HDD5GHZCHAN(5300, 60, 0) ,
204 HDD5GHZCHAN(5320, 64, 0) ,
205 HDD5GHZCHAN(5500,100, 0) ,
206 HDD5GHZCHAN(5520,104, 0) ,
207 HDD5GHZCHAN(5540,108, 0) ,
208 HDD5GHZCHAN(5560,112, 0) ,
209 HDD5GHZCHAN(5580,116, 0) ,
210 HDD5GHZCHAN(5600,120, 0) ,
211 HDD5GHZCHAN(5620,124, 0) ,
212 HDD5GHZCHAN(5640,128, 0) ,
213 HDD5GHZCHAN(5660,132, 0) ,
214 HDD5GHZCHAN(5680,136, 0) ,
215 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800216#ifdef FEATURE_WLAN_CH144
217 HDD5GHZCHAN(5720,144, 0) ,
218#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD5GHZCHAN(5745,149, 0) ,
220 HDD5GHZCHAN(5765,153, 0) ,
221 HDD5GHZCHAN(5785,157, 0) ,
222 HDD5GHZCHAN(5805,161, 0) ,
223 HDD5GHZCHAN(5825,165, 0) ,
224};
225
226static struct ieee80211_rate g_mode_rates[] =
227{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530228 HDD_G_MODE_RATETAB(10, 0x1, 0),
229 HDD_G_MODE_RATETAB(20, 0x2, 0),
230 HDD_G_MODE_RATETAB(55, 0x4, 0),
231 HDD_G_MODE_RATETAB(110, 0x8, 0),
232 HDD_G_MODE_RATETAB(60, 0x10, 0),
233 HDD_G_MODE_RATETAB(90, 0x20, 0),
234 HDD_G_MODE_RATETAB(120, 0x40, 0),
235 HDD_G_MODE_RATETAB(180, 0x80, 0),
236 HDD_G_MODE_RATETAB(240, 0x100, 0),
237 HDD_G_MODE_RATETAB(360, 0x200, 0),
238 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530240};
Jeff Johnson295189b2012-06-20 16:38:30 -0700241
242static struct ieee80211_rate a_mode_rates[] =
243{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530244 HDD_G_MODE_RATETAB(60, 0x10, 0),
245 HDD_G_MODE_RATETAB(90, 0x20, 0),
246 HDD_G_MODE_RATETAB(120, 0x40, 0),
247 HDD_G_MODE_RATETAB(180, 0x80, 0),
248 HDD_G_MODE_RATETAB(240, 0x100, 0),
249 HDD_G_MODE_RATETAB(360, 0x200, 0),
250 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700251 HDD_G_MODE_RATETAB(540, 0x800, 0),
252};
253
254static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
255{
256 .channels = hdd_channels_2_4_GHZ,
257 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
258 .band = IEEE80211_BAND_2GHZ,
259 .bitrates = g_mode_rates,
260 .n_bitrates = g_mode_rates_size,
261 .ht_cap.ht_supported = 1,
262 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
263 | IEEE80211_HT_CAP_GRN_FLD
264 | IEEE80211_HT_CAP_DSSSCCK40
265 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
266 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
267 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
268 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
269 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
270 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
271};
272
Jeff Johnson295189b2012-06-20 16:38:30 -0700273static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
274{
275 .channels = hdd_social_channels_2_4_GHZ,
276 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
277 .band = IEEE80211_BAND_2GHZ,
278 .bitrates = g_mode_rates,
279 .n_bitrates = g_mode_rates_size,
280 .ht_cap.ht_supported = 1,
281 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
282 | IEEE80211_HT_CAP_GRN_FLD
283 | IEEE80211_HT_CAP_DSSSCCK40
284 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
285 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
286 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
287 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
288 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
289 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
290};
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
292static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
293{
294 .channels = hdd_channels_5_GHZ,
295 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
296 .band = IEEE80211_BAND_5GHZ,
297 .bitrates = a_mode_rates,
298 .n_bitrates = a_mode_rates_size,
299 .ht_cap.ht_supported = 1,
300 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
301 | IEEE80211_HT_CAP_GRN_FLD
302 | IEEE80211_HT_CAP_DSSSCCK40
303 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
304 | IEEE80211_HT_CAP_SGI_40
305 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
306 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
307 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
308 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
309 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
310 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
311};
312
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530313/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 TX/RX direction for each kind of interface */
315static const struct ieee80211_txrx_stypes
316wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
317 [NL80211_IFTYPE_STATION] = {
318 .tx = 0xffff,
319 .rx = BIT(SIR_MAC_MGMT_ACTION) |
320 BIT(SIR_MAC_MGMT_PROBE_REQ),
321 },
322 [NL80211_IFTYPE_AP] = {
323 .tx = 0xffff,
324 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
325 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
326 BIT(SIR_MAC_MGMT_PROBE_REQ) |
327 BIT(SIR_MAC_MGMT_DISASSOC) |
328 BIT(SIR_MAC_MGMT_AUTH) |
329 BIT(SIR_MAC_MGMT_DEAUTH) |
330 BIT(SIR_MAC_MGMT_ACTION),
331 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700332 [NL80211_IFTYPE_ADHOC] = {
333 .tx = 0xffff,
334 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
336 BIT(SIR_MAC_MGMT_PROBE_REQ) |
337 BIT(SIR_MAC_MGMT_DISASSOC) |
338 BIT(SIR_MAC_MGMT_AUTH) |
339 BIT(SIR_MAC_MGMT_DEAUTH) |
340 BIT(SIR_MAC_MGMT_ACTION),
341 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 [NL80211_IFTYPE_P2P_CLIENT] = {
343 .tx = 0xffff,
344 .rx = BIT(SIR_MAC_MGMT_ACTION) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ),
346 },
347 [NL80211_IFTYPE_P2P_GO] = {
348 /* This is also same as for SoftAP */
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
351 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
352 BIT(SIR_MAC_MGMT_PROBE_REQ) |
353 BIT(SIR_MAC_MGMT_DISASSOC) |
354 BIT(SIR_MAC_MGMT_AUTH) |
355 BIT(SIR_MAC_MGMT_DEAUTH) |
356 BIT(SIR_MAC_MGMT_ACTION),
357 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700358};
359
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800360#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800361static const struct ieee80211_iface_limit
362wlan_hdd_iface_limit[] = {
363 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800364 /* max = 3 ; Our driver create two interfaces during driver init
365 * wlan0 and p2p0 interfaces. p2p0 is considered as station
366 * interface until a group is formed. In JB architecture, once the
367 * group is formed, interface type of p2p0 is changed to P2P GO or
368 * Client.
369 * When supplicant remove the group, it first issue a set interface
370 * cmd to change the mode back to Station. In JB this works fine as
371 * we advertize two station type interface during driver init.
372 * Some vendors create separate interface for P2P GO/Client,
373 * after group formation(Third one). But while group remove
374 * supplicant first tries to change the mode(3rd interface) to STATION
375 * But as we advertized only two sta type interfaces nl80211 was
376 * returning error for the third one which was leading to failure in
377 * delete interface. Ideally while removing the group, supplicant
378 * should not try to change the 3rd interface mode to Station type.
379 * Till we get a fix in wpa_supplicant, we advertize max STA
380 * interface type to 3
381 */
382 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383 .types = BIT(NL80211_IFTYPE_STATION),
384 },
385 {
386 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700387 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388 },
389 {
390 .max = 1,
391 .types = BIT(NL80211_IFTYPE_P2P_GO) |
392 BIT(NL80211_IFTYPE_P2P_CLIENT),
393 },
394};
395
396/* By default, only single channel concurrency is allowed */
397static struct ieee80211_iface_combination
398wlan_hdd_iface_combination = {
399 .limits = wlan_hdd_iface_limit,
400 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800401 /*
402 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
403 * and p2p0 interfaces during driver init
404 * Some vendors create separate interface for P2P operations.
405 * wlan0: STA interface
406 * p2p0: P2P Device interface, action frames goes
407 * through this interface.
408 * p2p-xx: P2P interface, After GO negotiation this interface is
409 * created for p2p operations(GO/CLIENT interface).
410 */
411 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800412 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
413 .beacon_int_infra_match = false,
414};
415#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416
Jeff Johnson295189b2012-06-20 16:38:30 -0700417static struct cfg80211_ops wlan_hdd_cfg80211_ops;
418
419/* Data rate 100KBPS based on IE Index */
420struct index_data_rate_type
421{
422 v_U8_t beacon_rate_index;
423 v_U16_t supported_rate[4];
424};
425
426/* 11B, 11G Rate table include Basic rate and Extended rate
427 The IDX field is the rate index
428 The HI field is the rate when RSSI is strong or being ignored
429 (in this case we report actual rate)
430 The MID field is the rate when RSSI is moderate
431 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
432 The LO field is the rate when RSSI is low
433 (in this case we don't report rates, actual current rate used)
434 */
435static const struct
436{
437 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700438 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700439} supported_data_rate[] =
440{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700441/* IDX HI HM LM LO (RSSI-based index */
442 {2, { 10, 10, 10, 0}},
443 {4, { 20, 20, 10, 0}},
444 {11, { 55, 20, 10, 0}},
445 {12, { 60, 55, 20, 0}},
446 {18, { 90, 55, 20, 0}},
447 {22, {110, 55, 20, 0}},
448 {24, {120, 90, 60, 0}},
449 {36, {180, 120, 60, 0}},
450 {44, {220, 180, 60, 0}},
451 {48, {240, 180, 90, 0}},
452 {66, {330, 180, 90, 0}},
453 {72, {360, 240, 90, 0}},
454 {96, {480, 240, 120, 0}},
455 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700456};
457
458/* MCS Based rate table */
459static struct index_data_rate_type supported_mcs_rate[] =
460{
461/* MCS L20 L40 S20 S40 */
462 {0, {65, 135, 72, 150}},
463 {1, {130, 270, 144, 300}},
464 {2, {195, 405, 217, 450}},
465 {3, {260, 540, 289, 600}},
466 {4, {390, 810, 433, 900}},
467 {5, {520, 1080, 578, 1200}},
468 {6, {585, 1215, 650, 1350}},
469 {7, {650, 1350, 722, 1500}}
470};
471
Leo Chang6f8870f2013-03-26 18:11:36 -0700472#ifdef WLAN_FEATURE_11AC
473
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530474#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700475
476struct index_vht_data_rate_type
477{
478 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530479 v_U16_t supported_VHT80_rate[2];
480 v_U16_t supported_VHT40_rate[2];
481 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700482};
483
484typedef enum
485{
486 DATA_RATE_11AC_MAX_MCS_7,
487 DATA_RATE_11AC_MAX_MCS_8,
488 DATA_RATE_11AC_MAX_MCS_9,
489 DATA_RATE_11AC_MAX_MCS_NA
490} eDataRate11ACMaxMcs;
491
492/* MCS Based VHT rate table */
493static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
494{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530495/* MCS L80 S80 L40 S40 L20 S40*/
496 {0, {293, 325}, {135, 150}, {65, 72}},
497 {1, {585, 650}, {270, 300}, {130, 144}},
498 {2, {878, 975}, {405, 450}, {195, 217}},
499 {3, {1170, 1300}, {540, 600}, {260, 289}},
500 {4, {1755, 1950}, {810, 900}, {390, 433}},
501 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
502 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
503 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
504 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
505 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700506};
507#endif /* WLAN_FEATURE_11AC */
508
Jeff Johnson295189b2012-06-20 16:38:30 -0700509extern struct net_device_ops net_ops_struct;
510
Leo Chang9056f462013-08-01 19:21:11 -0700511#ifdef WLAN_NL80211_TESTMODE
512enum wlan_hdd_tm_attr
513{
514 WLAN_HDD_TM_ATTR_INVALID = 0,
515 WLAN_HDD_TM_ATTR_CMD = 1,
516 WLAN_HDD_TM_ATTR_DATA = 2,
517 WLAN_HDD_TM_ATTR_TYPE = 3,
518 /* keep last */
519 WLAN_HDD_TM_ATTR_AFTER_LAST,
520 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
521};
522
523enum wlan_hdd_tm_cmd
524{
525 WLAN_HDD_TM_CMD_WLAN_HB = 1,
526};
527
528#define WLAN_HDD_TM_DATA_MAX_LEN 5000
529
530static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
531{
532 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
533 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
534 .len = WLAN_HDD_TM_DATA_MAX_LEN },
535};
536#endif /* WLAN_NL80211_TESTMODE */
537
Jeff Johnson295189b2012-06-20 16:38:30 -0700538/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530539 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530540 * This function is called by hdd_wlan_startup()
541 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530542 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700543 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530544struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700545{
546 struct wiphy *wiphy;
547 ENTER();
548
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530549 /*
550 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700551 */
552 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
553
554 if (!wiphy)
555 {
556 /* Print error and jump into err label and free the memory */
557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
558 return NULL;
559 }
560
561 return wiphy;
562}
563
564/*
565 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530566 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700567 * private ioctl to change the band value
568 */
569int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
570{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530571 int i, j;
572 eNVChannelEnabledType channelEnabledState;
573
Jeff Johnsone7245742012-09-05 17:12:55 -0700574 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530575 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700576 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530577
578 if (NULL == wiphy->bands[i])
579 {
580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
581 __func__, i);
582 continue;
583 }
584
585 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
586 {
587 struct ieee80211_supported_band *band = wiphy->bands[i];
588
589 channelEnabledState = vos_nv_getChannelEnabledState(
590 band->channels[j].hw_value);
591
592 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
593 {
594 // Enable Social channels for P2P
595 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
596 NV_CHANNEL_ENABLE == channelEnabledState)
597 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
598 else
599 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
600 continue;
601 }
602 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
603 {
604 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
605 continue;
606 }
607
608 if (NV_CHANNEL_DISABLE == channelEnabledState ||
609 NV_CHANNEL_INVALID == channelEnabledState)
610 {
611 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
612 }
613 else if (NV_CHANNEL_DFS == channelEnabledState)
614 {
615 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
616 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
617 }
618 else
619 {
620 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
621 |IEEE80211_CHAN_RADAR);
622 }
623 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 }
625 return 0;
626}
627/*
628 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530629 * This function is called by hdd_wlan_startup()
630 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 * This function is used to initialize and register wiphy structure.
632 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530633int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 struct wiphy *wiphy,
635 hdd_config_t *pCfg
636 )
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
Jeff Johnsone7245742012-09-05 17:12:55 -0700639 ENTER();
640
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 /* Now bind the underlying wlan device with wiphy */
642 set_wiphy_dev(wiphy, dev);
643
644 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700645
Kiet Lam6c583332013-10-14 05:37:09 +0530646#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700647 /* the flag for the other case would be initialzed in
648 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700649 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530650#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700651
Amar Singhalfddc28c2013-09-05 13:03:40 -0700652 /* This will disable updating of NL channels from passive to
653 * active if a beacon is received on passive channel. */
654 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700655
Amar Singhalfddc28c2013-09-05 13:03:40 -0700656
Amar Singhala49cbc52013-10-08 18:37:44 -0700657
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700659 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
660 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
661 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700662 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530663 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700664#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700665
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700666#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
667 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800668#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700669 || pCfg->isFastRoamIniFeatureEnabled
670#endif
671#ifdef FEATURE_WLAN_CCX
672 || pCfg->isCcxIniFeatureEnabled
673#endif
674 )
675 {
676 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
677 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800678#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800679#ifdef FEATURE_WLAN_TDLS
680 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
681 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
682#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530683#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530684 if (pCfg->configPNOScanSupport)
685 {
686 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
687 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
688 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
689 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
690 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530691#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800692
Amar Singhalfddc28c2013-09-05 13:03:40 -0700693#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700694 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
695 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700696 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700697 driver need to determine what to do with both
698 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700699
700 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700701#else
702 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700703#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700704
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530705 wiphy->max_scan_ssids = MAX_SCAN_SSID;
706
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530707 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700708
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530709 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530712 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700714 | BIT(NL80211_IFTYPE_P2P_CLIENT)
715 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700716 | BIT(NL80211_IFTYPE_AP);
717
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800719 if( pCfg->enableMCC )
720 {
721 /* Currently, supports up to two channels */
722 wlan_hdd_iface_combination.num_different_channels = 2;
723
724 if( !pCfg->allowMCCGODiffBI )
725 wlan_hdd_iface_combination.beacon_int_infra_match = true;
726
727 }
728 wiphy->iface_combinations = &wlan_hdd_iface_combination;
729 wiphy->n_iface_combinations = 1;
730#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800731
Jeff Johnson295189b2012-06-20 16:38:30 -0700732 /* Before registering we need to update the ht capabilitied based
733 * on ini values*/
734 if( !pCfg->ShortGI20MhzEnable )
735 {
736 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
737 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
738 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
739 }
740
741 if( !pCfg->ShortGI40MhzEnable )
742 {
743 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
744 }
745
746 if( !pCfg->nChannelBondingMode5GHz )
747 {
748 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
749 }
750
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530751 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
752 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
753
754 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
755 {
756
757 if (NULL == wiphy->bands[i])
758 {
759 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
760 __func__, i);
761 continue;
762 }
763
764 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
765 {
766 struct ieee80211_supported_band *band = wiphy->bands[i];
767
768 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
769 {
770 // Enable social channels for P2P
771 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
772 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
773 else
774 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
775 continue;
776 }
777 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
778 {
779 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
780 continue;
781 }
782 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 }
784 /*Initialise the supported cipher suite details*/
785 wiphy->cipher_suites = hdd_cipher_suites;
786 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
787
788 /*signal strength in mBm (100*dBm) */
789 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
790
791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 wiphy->max_remain_on_channel_duration = 1000;
793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700794
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530795 EXIT();
796 return 0;
797}
798
799/* In this function we are registering wiphy. */
800int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
801{
802 ENTER();
803 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 if (0 > wiphy_register(wiphy))
805 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530806 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
808 return -EIO;
809 }
810
811 EXIT();
812 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530813}
Jeff Johnson295189b2012-06-20 16:38:30 -0700814
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530815/* In this function we are updating channel list when,
816 regulatory domain is FCC and country code is US.
817 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
818 As per FCC smart phone is not a indoor device.
819 GO should not opeate on indoor channels */
820void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
821{
822 int j;
823 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
824 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
825 //Default counrtycode from NV at the time of wiphy initialization.
826 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
827 &defaultCountryCode[0]))
828 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700829 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530830 }
831 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
832 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530833 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
836 return;
837 }
838 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
839 {
840 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
841 // Mark UNII -1 band channel as passive
842 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
843 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
844 }
845 }
846}
847
Jeff Johnson295189b2012-06-20 16:38:30 -0700848/* In this function we will do all post VOS start initialization.
849 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530850 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700851*/
852void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
853{
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
855 /* Register for all P2P action, public action etc frames */
856 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
857
Jeff Johnsone7245742012-09-05 17:12:55 -0700858 ENTER();
859
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 /* Right now we are registering these frame when driver is getting
861 initialized. Once we will move to 2.6.37 kernel, in which we have
862 frame register ops, we will move this code as a part of that */
863 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530864 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
866
867 /* GAS Initial Response */
868 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
869 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530870
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 /* GAS Comeback Request */
872 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
873 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
874
875 /* GAS Comeback Response */
876 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
877 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
878
879 /* P2P Public Action */
880 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530881 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700882 P2P_PUBLIC_ACTION_FRAME_SIZE );
883
884 /* P2P Action */
885 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
886 (v_U8_t*)P2P_ACTION_FRAME,
887 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700888
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530889 /* WNM BSS Transition Request frame */
890 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
891 (v_U8_t*)WNM_BSS_ACTION_FRAME,
892 WNM_BSS_ACTION_FRAME_SIZE );
893
Chet Lanctot186b5732013-03-18 10:26:30 -0700894#ifdef WLAN_FEATURE_11W
895 /* SA Query Response Action Frame */
896 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
897 (v_U8_t*)SA_QUERY_FRAME_RSP,
898 SA_QUERY_FRAME_RSP_SIZE );
899#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700900}
901
902void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
903{
Jeff Johnson295189b2012-06-20 16:38:30 -0700904 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
905 /* Register for all P2P action, public action etc frames */
906 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
907
Jeff Johnsone7245742012-09-05 17:12:55 -0700908 ENTER();
909
Jeff Johnson295189b2012-06-20 16:38:30 -0700910 /* Right now we are registering these frame when driver is getting
911 initialized. Once we will move to 2.6.37 kernel, in which we have
912 frame register ops, we will move this code as a part of that */
913 /* GAS Initial Request */
914
915 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
916 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
917
918 /* GAS Initial Response */
919 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
920 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530921
Jeff Johnson295189b2012-06-20 16:38:30 -0700922 /* GAS Comeback Request */
923 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
924 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
925
926 /* GAS Comeback Response */
927 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
928 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
929
930 /* P2P Public Action */
931 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 P2P_PUBLIC_ACTION_FRAME_SIZE );
934
935 /* P2P Action */
936 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
937 (v_U8_t*)P2P_ACTION_FRAME,
938 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700939
940#ifdef WLAN_FEATURE_11W
941 /* SA Query Response Action Frame */
942 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
943 (v_U8_t*)SA_QUERY_FRAME_RSP,
944 SA_QUERY_FRAME_RSP_SIZE );
945#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700946}
947
948#ifdef FEATURE_WLAN_WAPI
949void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
950 const u8 *mac_addr, u8 *key , int key_Len)
951{
952 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
953 tCsrRoamSetKey setKey;
954 v_BOOL_t isConnected = TRUE;
955 int status = 0;
956 v_U32_t roamId= 0xFF;
957 tANI_U8 *pKeyPtr = NULL;
958 int n = 0;
959
Arif Hussain6d2a3322013-11-17 19:50:10 -0800960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 __func__,pAdapter->device_mode);
962
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530963 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 setKey.keyId = key_index; // Store Key ID
965 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
966 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
967 setKey.paeRole = 0 ; // the PAE role
968 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
969 {
970 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
971 }
972 else
973 {
974 isConnected = hdd_connIsConnected(pHddStaCtx);
975 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
976 }
977 setKey.keyLength = key_Len;
978 pKeyPtr = setKey.Key;
979 memcpy( pKeyPtr, key, key_Len);
980
Arif Hussain6d2a3322013-11-17 19:50:10 -0800981 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 __func__, key_Len);
983 for (n = 0 ; n < key_Len; n++)
984 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
985 __func__,n,setKey.Key[n]);
986
987 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
988 if ( isConnected )
989 {
990 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
991 pAdapter->sessionId, &setKey, &roamId );
992 }
993 if ( status != 0 )
994 {
995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
996 "[%4d] sme_RoamSetKey returned ERROR status= %d",
997 __LINE__, status );
998 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
999 }
1000}
1001#endif /* FEATURE_WLAN_WAPI*/
1002
1003#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301004int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001005 beacon_data_t **ppBeacon,
1006 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001007#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301008int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001009 beacon_data_t **ppBeacon,
1010 struct cfg80211_beacon_data *params,
1011 int dtim_period)
1012#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301013{
Jeff Johnson295189b2012-06-20 16:38:30 -07001014 int size;
1015 beacon_data_t *beacon = NULL;
1016 beacon_data_t *old = NULL;
1017 int head_len,tail_len;
1018
Jeff Johnsone7245742012-09-05 17:12:55 -07001019 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001020 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301021 {
1022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1023 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001026
1027 old = pAdapter->sessionCtx.ap.beacon;
1028
1029 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301030 {
1031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1032 FL("session(%d) old and new heads points to NULL"),
1033 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301035 }
1036
1037 if (params->tail && !params->tail_len)
1038 {
1039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1040 FL("tail_len is zero but tail is not NULL"));
1041 return -EINVAL;
1042 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
Jeff Johnson295189b2012-06-20 16:38:30 -07001044#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1045 /* Kernel 3.0 is not updating dtim_period for set beacon */
1046 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301047 {
1048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1049 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001052#endif
1053
1054 if(params->head)
1055 head_len = params->head_len;
1056 else
1057 head_len = old->head_len;
1058
1059 if(params->tail || !old)
1060 tail_len = params->tail_len;
1061 else
1062 tail_len = old->tail_len;
1063
1064 size = sizeof(beacon_data_t) + head_len + tail_len;
1065
1066 beacon = kzalloc(size, GFP_KERNEL);
1067
1068 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301069 {
1070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1071 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001074
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001075#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 if(params->dtim_period || !old )
1077 beacon->dtim_period = params->dtim_period;
1078 else
1079 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001080#else
1081 if(dtim_period || !old )
1082 beacon->dtim_period = dtim_period;
1083 else
1084 beacon->dtim_period = old->dtim_period;
1085#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301086
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1088 beacon->tail = beacon->head + head_len;
1089 beacon->head_len = head_len;
1090 beacon->tail_len = tail_len;
1091
1092 if(params->head) {
1093 memcpy (beacon->head,params->head,beacon->head_len);
1094 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301095 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 if(old)
1097 memcpy (beacon->head,old->head,beacon->head_len);
1098 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301099
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 if(params->tail) {
1101 memcpy (beacon->tail,params->tail,beacon->tail_len);
1102 }
1103 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301104 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001105 memcpy (beacon->tail,old->tail,beacon->tail_len);
1106 }
1107
1108 *ppBeacon = beacon;
1109
1110 kfree(old);
1111
1112 return 0;
1113
1114}
Jeff Johnson295189b2012-06-20 16:38:30 -07001115
1116v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1117{
1118 int left = length;
1119 v_U8_t *ptr = pIes;
1120 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301121
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301123 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 elem_id = ptr[0];
1125 elem_len = ptr[1];
1126 left -= 2;
1127 if(elem_len > left)
1128 {
1129 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001130 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001131 eid,elem_len,left);
1132 return NULL;
1133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301134 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 {
1136 return ptr;
1137 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301138
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 left -= elem_len;
1140 ptr += (elem_len + 2);
1141 }
1142 return NULL;
1143}
1144
Jeff Johnson295189b2012-06-20 16:38:30 -07001145/* Check if rate is 11g rate or not */
1146static int wlan_hdd_rate_is_11g(u8 rate)
1147{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001148 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 u8 i;
1150 for (i = 0; i < 8; i++)
1151 {
1152 if(rate == gRateArray[i])
1153 return TRUE;
1154 }
1155 return FALSE;
1156}
1157
1158/* Check for 11g rate and set proper 11g only mode */
1159static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1160 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1161{
1162 u8 i, num_rates = pIe[0];
1163
1164 pIe += 1;
1165 for ( i = 0; i < num_rates; i++)
1166 {
1167 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1168 {
1169 /* If rate set have 11g rate than change the mode to 11G */
1170 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1171 if (pIe[i] & BASIC_RATE_MASK)
1172 {
1173 /* If we have 11g rate as basic rate, it means mode
1174 is 11g only mode.
1175 */
1176 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1177 *pCheckRatesfor11g = FALSE;
1178 }
1179 }
1180 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1181 {
1182 *require_ht = TRUE;
1183 }
1184 }
1185 return;
1186}
1187
1188static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1189{
1190 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1191 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1192 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1193 u8 checkRatesfor11g = TRUE;
1194 u8 require_ht = FALSE;
1195 u8 *pIe=NULL;
1196
1197 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1198
1199 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1200 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1201 if (pIe != NULL)
1202 {
1203 pIe += 1;
1204 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1205 &pConfig->SapHw_mode);
1206 }
1207
1208 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1209 WLAN_EID_EXT_SUPP_RATES);
1210 if (pIe != NULL)
1211 {
1212
1213 pIe += 1;
1214 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1215 &pConfig->SapHw_mode);
1216 }
1217
1218 if( pConfig->channel > 14 )
1219 {
1220 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1221 }
1222
1223 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1224 WLAN_EID_HT_CAPABILITY);
1225
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301226 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 {
1228 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1229 if(require_ht)
1230 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1231 }
1232}
1233
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301234static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1235 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1236{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001237 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301238 v_U8_t *pIe = NULL;
1239 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1240
1241 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1242 pBeacon->tail, pBeacon->tail_len);
1243
1244 if (pIe)
1245 {
1246 ielen = pIe[1] + 2;
1247 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1248 {
1249 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1250 }
1251 else
1252 {
1253 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1254 return -EINVAL;
1255 }
1256 *total_ielen += ielen;
1257 }
1258 return 0;
1259}
1260
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001261static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1262 v_U8_t *genie, v_U8_t *total_ielen)
1263{
1264 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1265 int left = pBeacon->tail_len;
1266 v_U8_t *ptr = pBeacon->tail;
1267 v_U8_t elem_id, elem_len;
1268 v_U16_t ielen = 0;
1269
1270 if ( NULL == ptr || 0 == left )
1271 return;
1272
1273 while (left >= 2)
1274 {
1275 elem_id = ptr[0];
1276 elem_len = ptr[1];
1277 left -= 2;
1278 if (elem_len > left)
1279 {
1280 hddLog( VOS_TRACE_LEVEL_ERROR,
1281 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1282 elem_id, elem_len, left);
1283 return;
1284 }
1285 if (IE_EID_VENDOR == elem_id)
1286 {
1287 /* skipping the VSIE's which we don't want to include or
1288 * it will be included by existing code
1289 */
1290 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1291#ifdef WLAN_FEATURE_WFD
1292 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1293#endif
1294 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1295 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1296 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1297 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1298 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1299 {
1300 ielen = ptr[1] + 2;
1301 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1302 {
1303 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1304 *total_ielen += ielen;
1305 }
1306 else
1307 {
1308 hddLog( VOS_TRACE_LEVEL_ERROR,
1309 "IE Length is too big "
1310 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1311 elem_id, elem_len, *total_ielen);
1312 }
1313 }
1314 }
1315
1316 left -= elem_len;
1317 ptr += (elem_len + 2);
1318 }
1319 return;
1320}
1321
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001322#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001323static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1324 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001325#else
1326static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1327 struct cfg80211_beacon_data *params)
1328#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001329{
1330 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301331 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001333 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001334
1335 genie = vos_mem_malloc(MAX_GENIE_LEN);
1336
1337 if(genie == NULL) {
1338
1339 return -ENOMEM;
1340 }
1341
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301342 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1343 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301345 hddLog(LOGE,
1346 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301347 ret = -EINVAL;
1348 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001349 }
1350
1351#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301352 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1353 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1354 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301355 hddLog(LOGE,
1356 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301357 ret = -EINVAL;
1358 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 }
1360#endif
1361
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301362 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1363 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001364 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301365 hddLog(LOGE,
1366 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301367 ret = -EINVAL;
1368 goto done;
1369 }
1370
1371 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1372 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001373 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001375
1376 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1377 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1378 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1379 {
1380 hddLog(LOGE,
1381 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001382 ret = -EINVAL;
1383 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001384 }
1385
1386 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1387 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1388 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1389 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1390 ==eHAL_STATUS_FAILURE)
1391 {
1392 hddLog(LOGE,
1393 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001394 ret = -EINVAL;
1395 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001396 }
1397
1398 // Added for ProResp IE
1399 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1400 {
1401 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1402 u8 probe_rsp_ie_len[3] = {0};
1403 u8 counter = 0;
1404 /* Check Probe Resp Length if it is greater then 255 then Store
1405 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1406 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1407 Store More then 255 bytes into One Variable.
1408 */
1409 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1410 {
1411 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1412 {
1413 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1414 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1415 }
1416 else
1417 {
1418 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1419 rem_probe_resp_ie_len = 0;
1420 }
1421 }
1422
1423 rem_probe_resp_ie_len = 0;
1424
1425 if (probe_rsp_ie_len[0] > 0)
1426 {
1427 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1428 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1429 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1430 probe_rsp_ie_len[0], NULL,
1431 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1432 {
1433 hddLog(LOGE,
1434 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001435 ret = -EINVAL;
1436 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 }
1438 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1439 }
1440
1441 if (probe_rsp_ie_len[1] > 0)
1442 {
1443 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1444 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1445 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1446 probe_rsp_ie_len[1], NULL,
1447 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1448 {
1449 hddLog(LOGE,
1450 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001451 ret = -EINVAL;
1452 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001453 }
1454 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1455 }
1456
1457 if (probe_rsp_ie_len[2] > 0)
1458 {
1459 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1460 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1461 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1462 probe_rsp_ie_len[2], NULL,
1463 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1464 {
1465 hddLog(LOGE,
1466 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001467 ret = -EINVAL;
1468 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001469 }
1470 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1471 }
1472
1473 if (probe_rsp_ie_len[1] == 0 )
1474 {
1475 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1476 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1477 eANI_BOOLEAN_FALSE) )
1478 {
1479 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001480 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001481 }
1482 }
1483
1484 if (probe_rsp_ie_len[2] == 0 )
1485 {
1486 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1487 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1488 eANI_BOOLEAN_FALSE) )
1489 {
1490 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001491 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001492 }
1493 }
1494
1495 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1496 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1497 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1498 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1499 == eHAL_STATUS_FAILURE)
1500 {
1501 hddLog(LOGE,
1502 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001503 ret = -EINVAL;
1504 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001505 }
1506 }
1507 else
1508 {
1509 // Reset WNI_CFG_PROBE_RSP Flags
1510 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1511
1512 hddLog(VOS_TRACE_LEVEL_INFO,
1513 "%s: No Probe Response IE received in set beacon",
1514 __func__);
1515 }
1516
1517 // Added for AssocResp IE
1518 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1519 {
1520 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1521 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1522 params->assocresp_ies_len, NULL,
1523 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1524 {
1525 hddLog(LOGE,
1526 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001527 ret = -EINVAL;
1528 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 }
1530
1531 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1532 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1533 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1534 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1535 == eHAL_STATUS_FAILURE)
1536 {
1537 hddLog(LOGE,
1538 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001539 ret = -EINVAL;
1540 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001541 }
1542 }
1543 else
1544 {
1545 hddLog(VOS_TRACE_LEVEL_INFO,
1546 "%s: No Assoc Response IE received in set beacon",
1547 __func__);
1548
1549 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1550 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1551 eANI_BOOLEAN_FALSE) )
1552 {
1553 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001554 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001555 }
1556 }
1557
Jeff Johnsone7245742012-09-05 17:12:55 -07001558done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301560 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001561}
Jeff Johnson295189b2012-06-20 16:38:30 -07001562
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301563/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001564 * FUNCTION: wlan_hdd_validate_operation_channel
1565 * called by wlan_hdd_cfg80211_start_bss() and
1566 * wlan_hdd_cfg80211_set_channel()
1567 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301568 * channel list.
1569 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001570VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001571{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301572
Jeff Johnson295189b2012-06-20 16:38:30 -07001573 v_U32_t num_ch = 0;
1574 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1575 u32 indx = 0;
1576 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301577 v_U8_t fValidChannel = FALSE, count = 0;
1578 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301579
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1581
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301582 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001583 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301584 /* Validate the channel */
1585 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001586 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301587 if ( channel == rfChannels[count].channelNum )
1588 {
1589 fValidChannel = TRUE;
1590 break;
1591 }
1592 }
1593 if (fValidChannel != TRUE)
1594 {
1595 hddLog(VOS_TRACE_LEVEL_ERROR,
1596 "%s: Invalid Channel [%d]", __func__, channel);
1597 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001598 }
1599 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301600 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001601 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301602 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1603 valid_ch, &num_ch))
1604 {
1605 hddLog(VOS_TRACE_LEVEL_ERROR,
1606 "%s: failed to get valid channel list", __func__);
1607 return VOS_STATUS_E_FAILURE;
1608 }
1609 for (indx = 0; indx < num_ch; indx++)
1610 {
1611 if (channel == valid_ch[indx])
1612 {
1613 break;
1614 }
1615 }
1616
1617 if (indx >= num_ch)
1618 {
1619 hddLog(VOS_TRACE_LEVEL_ERROR,
1620 "%s: Invalid Channel [%d]", __func__, channel);
1621 return VOS_STATUS_E_FAILURE;
1622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001623 }
1624 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301625
Jeff Johnson295189b2012-06-20 16:38:30 -07001626}
1627
Viral Modi3a32cc52013-02-08 11:14:52 -08001628/**
1629 * FUNCTION: wlan_hdd_cfg80211_set_channel
1630 * This function is used to set the channel number
1631 */
1632static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1633 struct ieee80211_channel *chan,
1634 enum nl80211_channel_type channel_type
1635 )
1636{
1637 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001638 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001639 hdd_adapter_t *pAdapter = NULL;
1640 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301641 hdd_context_t *pHddCtx;
1642 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001643
1644 ENTER();
1645
1646 if( NULL == dev )
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001649 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001650 return -ENODEV;
1651 }
1652 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1653
1654 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001655 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001656 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301657
1658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1659 status = wlan_hdd_validate_context(pHddCtx);
1660
1661 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "%s: HDD context is not valid", __func__);
1665 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001666 }
1667
1668 /*
1669 * Do freq to chan conversion
1670 * TODO: for 11a
1671 */
1672
1673 channel = ieee80211_frequency_to_channel(freq);
1674
1675 /* Check freq range */
1676 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1677 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1678 {
1679 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001680 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001681 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1682 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1683 return -EINVAL;
1684 }
1685
1686 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1687
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301688 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1689 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001690 {
1691 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1692 {
1693 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001694 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001695 return -EINVAL;
1696 }
1697 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1698 "%s: set channel to [%d] for device mode =%d",
1699 __func__, channel,pAdapter->device_mode);
1700 }
1701 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001702 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001703 )
1704 {
1705 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1706 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1707 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1708
1709 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1710 {
1711 /* Link is up then return cant set channel*/
1712 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001713 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001714 return -EINVAL;
1715 }
1716
1717 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1718 pHddStaCtx->conn_info.operationChannel = channel;
1719 pRoamProfile->ChannelInfo.ChannelList =
1720 &pHddStaCtx->conn_info.operationChannel;
1721 }
1722 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001723 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001724 )
1725 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301726 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1727 {
1728 if(VOS_STATUS_SUCCESS !=
1729 wlan_hdd_validate_operation_channel(pAdapter,channel))
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001732 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301733 return -EINVAL;
1734 }
1735 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1736 }
1737 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001738 {
1739 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1740
1741 /* If auto channel selection is configured as enable/ 1 then ignore
1742 channel set by supplicant
1743 */
1744 if ( cfg_param->apAutoChannelSelection )
1745 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301746 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1747 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001748 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1749 "%s: set channel to auto channel (0) for device mode =%d",
1750 __func__, pAdapter->device_mode);
1751 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301752 else
1753 {
1754 if(VOS_STATUS_SUCCESS !=
1755 wlan_hdd_validate_operation_channel(pAdapter,channel))
1756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001758 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301759 return -EINVAL;
1760 }
1761 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1762 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001763 }
1764 }
1765 else
1766 {
1767 hddLog(VOS_TRACE_LEVEL_FATAL,
1768 "%s: Invalid device mode failed to set valid channel", __func__);
1769 return -EINVAL;
1770 }
1771 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301772 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001773}
1774
Jeff Johnson295189b2012-06-20 16:38:30 -07001775#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1776static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1777 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001778#else
1779static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1780 struct cfg80211_beacon_data *params,
1781 const u8 *ssid, size_t ssid_len,
1782 enum nl80211_hidden_ssid hidden_ssid)
1783#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001784{
1785 tsap_Config_t *pConfig;
1786 beacon_data_t *pBeacon = NULL;
1787 struct ieee80211_mgmt *pMgmt_frame;
1788 v_U8_t *pIe=NULL;
1789 v_U16_t capab_info;
1790 eCsrAuthType RSNAuthType;
1791 eCsrEncryptionType RSNEncryptType;
1792 eCsrEncryptionType mcRSNEncryptType;
1793 int status = VOS_STATUS_SUCCESS;
1794 tpWLAN_SAPEventCB pSapEventCallback;
1795 hdd_hostapd_state_t *pHostapdState;
1796 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1797 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301798 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001799 struct qc_mac_acl_entry *acl_entry = NULL;
1800 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001801 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001802
1803 ENTER();
1804
1805 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1806
1807 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1808
1809 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1810
1811 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1812
1813 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1814
1815 //channel is already set in the set_channel Call back
1816 //pConfig->channel = pCommitConfig->channel;
1817
1818 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301819 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001820 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1821
1822 pConfig->dtim_period = pBeacon->dtim_period;
1823
Arif Hussain6d2a3322013-11-17 19:50:10 -08001824 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001825 pConfig->dtim_period);
1826
1827
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001828 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001829 {
1830 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301832 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1833 {
1834 tANI_BOOLEAN restartNeeded;
1835 pConfig->ieee80211d = 1;
1836 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1837 sme_setRegInfo(hHal, pConfig->countryCode);
1838 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1839 }
1840 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001842 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001843 pConfig->ieee80211d = 1;
1844 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1845 sme_setRegInfo(hHal, pConfig->countryCode);
1846 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001848 else
1849 {
1850 pConfig->ieee80211d = 0;
1851 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301852 /*
1853 * If auto channel is configured i.e. channel is 0,
1854 * so skip channel validation.
1855 */
1856 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1857 {
1858 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001861 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301862 return -EINVAL;
1863 }
1864 }
1865 else
1866 {
1867 if(1 != pHddCtx->is_dynamic_channel_range_set)
1868 {
1869 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1870 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1871 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1872 }
1873 pHddCtx->is_dynamic_channel_range_set = 0;
1874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001876 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001877 {
1878 pConfig->ieee80211d = 0;
1879 }
1880 pConfig->authType = eSAP_AUTO_SWITCH;
1881
1882 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301883
1884 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1886
1887 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1888
1889 /*Set wps station to configured*/
1890 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1891
1892 if(pIe)
1893 {
1894 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1895 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001896 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 return -EINVAL;
1898 }
1899 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1900 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001901 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 /* Check 15 bit of WPS IE as it contain information for wps state
1903 * WPS state
1904 */
1905 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1906 {
1907 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1908 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1909 {
1910 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1911 }
1912 }
1913 }
1914 else
1915 {
1916 pConfig->wps_state = SAP_WPS_DISABLED;
1917 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301918 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001919
1920 pConfig->RSNWPAReqIELength = 0;
1921 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301922 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 WLAN_EID_RSN);
1924 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301925 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1927 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1928 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301929 /* The actual processing may eventually be more extensive than
1930 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 * by the app.
1932 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301933 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001934 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1935 &RSNEncryptType,
1936 &mcRSNEncryptType,
1937 &RSNAuthType,
1938 pConfig->pRSNWPAReqIE[1]+2,
1939 pConfig->pRSNWPAReqIE );
1940
1941 if( VOS_STATUS_SUCCESS == status )
1942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301943 /* Now copy over all the security attributes you have
1944 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 * */
1946 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1947 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1948 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1949 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301950 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001951 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1953 }
1954 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301955
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1957 pBeacon->tail, pBeacon->tail_len);
1958
1959 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1960 {
1961 if (pConfig->pRSNWPAReqIE)
1962 {
1963 /*Mixed mode WPA/WPA2*/
1964 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1965 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1966 }
1967 else
1968 {
1969 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1970 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1971 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301972 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1974 &RSNEncryptType,
1975 &mcRSNEncryptType,
1976 &RSNAuthType,
1977 pConfig->pRSNWPAReqIE[1]+2,
1978 pConfig->pRSNWPAReqIE );
1979
1980 if( VOS_STATUS_SUCCESS == status )
1981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301982 /* Now copy over all the security attributes you have
1983 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 * */
1985 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1986 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1987 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1988 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301989 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001990 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1992 }
1993 }
1994 }
1995
Jeff Johnson4416a782013-03-25 14:17:50 -07001996 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1997 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1998 return -EINVAL;
1999 }
2000
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2002
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002003#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 if (params->ssid != NULL)
2005 {
2006 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2007 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2008 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2009 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2010 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002011#else
2012 if (ssid != NULL)
2013 {
2014 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2015 pConfig->SSIDinfo.ssid.length = ssid_len;
2016 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2017 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2018 }
2019#endif
2020
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302021 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302023
Jeff Johnson295189b2012-06-20 16:38:30 -07002024 /* default value */
2025 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2026 pConfig->num_accept_mac = 0;
2027 pConfig->num_deny_mac = 0;
2028
2029 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2030 pBeacon->tail, pBeacon->tail_len);
2031
2032 /* pIe for black list is following form:
2033 type : 1 byte
2034 length : 1 byte
2035 OUI : 4 bytes
2036 acl type : 1 byte
2037 no of mac addr in black list: 1 byte
2038 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302039 */
2040 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 {
2042 pConfig->SapMacaddr_acl = pIe[6];
2043 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002044 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302046 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2047 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2049 for (i = 0; i < pConfig->num_deny_mac; i++)
2050 {
2051 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2052 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302053 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 }
2055 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2056 pBeacon->tail, pBeacon->tail_len);
2057
2058 /* pIe for white list is following form:
2059 type : 1 byte
2060 length : 1 byte
2061 OUI : 4 bytes
2062 acl type : 1 byte
2063 no of mac addr in white list: 1 byte
2064 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302065 */
2066 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002067 {
2068 pConfig->SapMacaddr_acl = pIe[6];
2069 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002070 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302072 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2073 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2075 for (i = 0; i < pConfig->num_accept_mac; i++)
2076 {
2077 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2078 acl_entry++;
2079 }
2080 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302081
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2083
Jeff Johnsone7245742012-09-05 17:12:55 -07002084#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002085 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302086 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2087 * 11ac in .ini and 11ac is supported by both host and firmware.
2088 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2089 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002090 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2091 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302092 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002093 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302094 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2095 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002096 {
2097 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002098
2099 /* Disable VHT support in 2.4 GHz band */
2100 if (pConfig->channel <= 14 &&
2101 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2102 {
2103 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2104 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002105 }
2106#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002108 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2109 {
2110 sme_SelectCBMode(hHal,
2111 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2112 pConfig->channel);
2113 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 // ht_capab is not what the name conveys,this is used for protection bitmap
2115 pConfig->ht_capab =
2116 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2117
2118 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2119 {
2120 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2121 return -EINVAL;
2122 }
2123
2124 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302125 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2127 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302128 pConfig->obssProtEnabled =
2129 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002130
Arif Hussain6d2a3322013-11-17 19:50:10 -08002131 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002133 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2134 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2135 (int)pConfig->channel);
2136 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2137 pConfig->SapHw_mode, pConfig->privacy,
2138 pConfig->authType);
2139 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2140 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2141 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2142 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002143
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302144 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002145 {
2146 //Bss already started. just return.
2147 //TODO Probably it should update some beacon params.
2148 hddLog( LOGE, "Bss Already started...Ignore the request");
2149 EXIT();
2150 return 0;
2151 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302152
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 pConfig->persona = pHostapdAdapter->device_mode;
2154
2155 pSapEventCallback = hdd_hostapd_SAPEventCB;
2156 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2157 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2158 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002159 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002160 return -EINVAL;
2161 }
2162
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302163 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002164 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2165
2166 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302167
Jeff Johnson295189b2012-06-20 16:38:30 -07002168 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302169 {
2170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002171 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002172 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 VOS_ASSERT(0);
2174 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302175
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 //Succesfully started Bss update the state bit.
2177 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2178
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002179#ifdef WLAN_FEATURE_P2P_DEBUG
2180 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2181 {
2182 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2183 {
2184 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2185 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002186 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002187 }
2188 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2189 {
2190 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2191 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002192 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002193 }
2194 }
2195#endif
2196
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 pHostapdState->bCommit = TRUE;
2198 EXIT();
2199
2200 return 0;
2201}
2202
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002203#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302204static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2205 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002206 struct beacon_parameters *params)
2207{
2208 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302209 hdd_context_t *pHddCtx;
2210 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002211
2212 ENTER();
2213
Arif Hussain6d2a3322013-11-17 19:50:10 -08002214 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002215
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302216 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2217 status = wlan_hdd_validate_context(pHddCtx);
2218
2219 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002220 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2222 "%s: HDD context is not valid", __func__);
2223 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002224 }
2225
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302226 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 )
2229 {
2230 beacon_data_t *old,*new;
2231
2232 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302233
Jeff Johnson295189b2012-06-20 16:38:30 -07002234 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302235 {
2236 hddLog(VOS_TRACE_LEVEL_WARN,
2237 FL("already beacon info added to session(%d)"),
2238 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302240 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002241
2242 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2243
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302244 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 {
2246 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002247 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 return -EINVAL;
2249 }
2250
2251 pAdapter->sessionCtx.ap.beacon = new;
2252
2253 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2254 }
2255
2256 EXIT();
2257 return status;
2258}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302259
2260static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 struct net_device *dev,
2262 struct beacon_parameters *params)
2263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302264 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302265 hdd_context_t *pHddCtx;
2266 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002267
2268 ENTER();
2269
Arif Hussain6d2a3322013-11-17 19:50:10 -08002270 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 __func__,pAdapter->device_mode);
2272
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302273 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2274 status = wlan_hdd_validate_context(pHddCtx);
2275
2276 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002277 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2279 "%s: HDD context is not valid", __func__);
2280 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002281 }
2282
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302283 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302285 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 {
2287 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302288
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302290
Jeff Johnson295189b2012-06-20 16:38:30 -07002291 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302292 {
2293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2294 FL("session(%d) old and new heads points to NULL"),
2295 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002296 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002298
2299 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2300
2301 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302302 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002303 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 return -EINVAL;
2305 }
2306
2307 pAdapter->sessionCtx.ap.beacon = new;
2308
2309 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2310 }
2311
2312 EXIT();
2313 return status;
2314}
2315
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002316#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2317
2318#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002319static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2320 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002321#else
2322static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2323 struct net_device *dev)
2324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002325{
2326 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002327 hdd_context_t *pHddCtx = NULL;
2328 hdd_scaninfo_t *pScanInfo = NULL;
2329 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302330 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002331
2332 ENTER();
2333
2334 if (NULL == pAdapter)
2335 {
2336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002337 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 return -ENODEV;
2339 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002340
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302341 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2342 status = wlan_hdd_validate_context(pHddCtx);
2343
2344 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "%s: HDD context is not valid", __func__);
2348 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002349 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002350
2351 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2352 if (NULL == staAdapter)
2353 {
2354 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2355 if (NULL == staAdapter)
2356 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2358 "%s: HDD adapter context for STA/P2P-CLI is Null",
2359 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002360 }
2361 }
2362
2363 pScanInfo = &pHddCtx->scan_info;
2364
Arif Hussain6d2a3322013-11-17 19:50:10 -08002365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 __func__,pAdapter->device_mode);
2367
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002368 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002369 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302370 long ret;
2371
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002372 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05302373 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302374 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002375 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002376 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302377 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002378 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302380 FL("Timeout occurred while waiting for abortscan %ld"),
2381 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002382
2383 if (pHddCtx->isLogpInProgress)
2384 {
2385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2386 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302387
2388 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002389 return -EAGAIN;
2390 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002391 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002392 }
2393 }
2394
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302395 hdd_hostapd_stop(dev);
2396
Jeff Johnson295189b2012-06-20 16:38:30 -07002397 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002398 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002399 )
2400 {
2401 beacon_data_t *old;
2402
2403 old = pAdapter->sessionCtx.ap.beacon;
2404
2405 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 FL("session(%d) beacon data points to NULL"),
2409 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002410 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002412
Jeff Johnson295189b2012-06-20 16:38:30 -07002413 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002414
2415 mutex_lock(&pHddCtx->sap_lock);
2416 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2417 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002418 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002419 {
2420 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2421
2422 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2423
2424 if (!VOS_IS_STATUS_SUCCESS(status))
2425 {
2426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002427 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002428 VOS_ASSERT(0);
2429 }
2430 }
2431 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2432 }
2433 mutex_unlock(&pHddCtx->sap_lock);
2434
2435 if(status != VOS_STATUS_SUCCESS)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002438 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002439 return -EINVAL;
2440 }
2441
Jeff Johnson4416a782013-03-25 14:17:50 -07002442 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002443 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2444 ==eHAL_STATUS_FAILURE)
2445 {
2446 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002447 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002448 }
2449
Jeff Johnson4416a782013-03-25 14:17:50 -07002450 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002451 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2452 eANI_BOOLEAN_FALSE) )
2453 {
2454 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002455 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 }
2457
2458 // Reset WNI_CFG_PROBE_RSP Flags
2459 wlan_hdd_reset_prob_rspies(pAdapter);
2460
2461 pAdapter->sessionCtx.ap.beacon = NULL;
2462 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002463#ifdef WLAN_FEATURE_P2P_DEBUG
2464 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2465 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2466 {
2467 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2468 "GO got removed");
2469 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2470 }
2471#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002472 }
2473 EXIT();
2474 return status;
2475}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002476
2477#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2478
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302479static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2480 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002481 struct cfg80211_ap_settings *params)
2482{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302483 hdd_adapter_t *pAdapter;
2484 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302485 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002486
2487 ENTER();
2488
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302489 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002490 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302492 "%s: Device is Null", __func__);
2493 return -ENODEV;
2494 }
2495
2496 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2497 if (NULL == pAdapter)
2498 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302500 "%s: HDD adapter is Null", __func__);
2501 return -ENODEV;
2502 }
2503
2504 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2505 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302507 "%s: HDD adapter magic is invalid", __func__);
2508 return -ENODEV;
2509 }
2510
2511 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302512 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302513
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302514 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302515 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2517 "%s: HDD context is not valid", __func__);
2518 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302519 }
2520
2521 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2522 __func__, pAdapter->device_mode);
2523
2524 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002525 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002526 )
2527 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302528 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002529
2530 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302531
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002532 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302533 {
2534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2535 FL("already beacon info added to session(%d)"),
2536 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002537 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302538 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002539
2540 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2541
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302542 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002543 {
2544 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302545 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002546 return -EINVAL;
2547 }
2548 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002550 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2551#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2552 params->channel, params->channel_type);
2553#else
2554 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2555#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002556#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002557 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2558 params->ssid_len, params->hidden_ssid);
2559 }
2560
2561 EXIT();
2562 return status;
2563}
2564
2565
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302566static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002567 struct net_device *dev,
2568 struct cfg80211_beacon_data *params)
2569{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302571 hdd_context_t *pHddCtx;
2572 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002573
2574 ENTER();
2575
Arif Hussain6d2a3322013-11-17 19:50:10 -08002576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002577 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302578
2579 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2580 status = wlan_hdd_validate_context(pHddCtx);
2581
2582 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002583 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2585 "%s: HDD context is not valid", __func__);
2586 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002587 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002588
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302589 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002590 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302591 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002592 {
2593 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302594
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002595 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302596
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002597 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302598 {
2599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2600 FL("session(%d) beacon data points to NULL"),
2601 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002602 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302603 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002604
2605 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2606
2607 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302608 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002609 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002610 return -EINVAL;
2611 }
2612
2613 pAdapter->sessionCtx.ap.beacon = new;
2614
2615 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2616 }
2617
2618 EXIT();
2619 return status;
2620}
2621
2622#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2623
Jeff Johnson295189b2012-06-20 16:38:30 -07002624
2625static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2626 struct net_device *dev,
2627 struct bss_parameters *params)
2628{
2629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2630
2631 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302632
Arif Hussain6d2a3322013-11-17 19:50:10 -08002633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002634 __func__,pAdapter->device_mode);
2635
2636 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302638 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002639 {
2640 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2641 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302642 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 {
2644 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 }
2647
2648 EXIT();
2649 return 0;
2650}
2651
Kiet Lam10841362013-11-01 11:36:50 +05302652/* FUNCTION: wlan_hdd_change_country_code_cd
2653* to wait for contry code completion
2654*/
2655void* wlan_hdd_change_country_code_cb(void *pAdapter)
2656{
2657 hdd_adapter_t *call_back_pAdapter = pAdapter;
2658 complete(&call_back_pAdapter->change_country_code);
2659 return NULL;
2660}
2661
Jeff Johnson295189b2012-06-20 16:38:30 -07002662/*
2663 * FUNCTION: wlan_hdd_cfg80211_change_iface
2664 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2665 */
2666int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2667 struct net_device *ndev,
2668 enum nl80211_iftype type,
2669 u32 *flags,
2670 struct vif_params *params
2671 )
2672{
2673 struct wireless_dev *wdev;
2674 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2675 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002676 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002677 tCsrRoamProfile *pRoamProfile = NULL;
2678 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302679 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 eMib_dot11DesiredBssType connectedBssType;
2681 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302682 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002683
2684 ENTER();
2685
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302686 status = wlan_hdd_validate_context(pHddCtx);
2687
2688 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002689 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2691 "%s: HDD context is not valid", __func__);
2692 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 }
2694
2695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2696 __func__, pAdapter->device_mode);
2697
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302698 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 wdev = ndev->ieee80211_ptr;
2700
2701#ifdef WLAN_BTAMP_FEATURE
2702 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2703 (NL80211_IFTYPE_ADHOC == type)||
2704 (NL80211_IFTYPE_AP == type)||
2705 (NL80211_IFTYPE_P2P_GO == type))
2706 {
2707 pHddCtx->isAmpAllowed = VOS_FALSE;
2708 // stop AMP traffic
2709 status = WLANBAP_StopAmp();
2710 if(VOS_STATUS_SUCCESS != status )
2711 {
2712 pHddCtx->isAmpAllowed = VOS_TRUE;
2713 hddLog(VOS_TRACE_LEVEL_FATAL,
2714 "%s: Failed to stop AMP", __func__);
2715 return -EINVAL;
2716 }
2717 }
2718#endif //WLAN_BTAMP_FEATURE
2719 /* Reset the current device mode bit mask*/
2720 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2721
2722 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002723 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002724 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 )
2726 {
2727 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2728 pRoamProfile = &pWextState->roamProfile;
2729 LastBSSType = pRoamProfile->BSSType;
2730
2731 switch (type)
2732 {
2733 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002734 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002735 hddLog(VOS_TRACE_LEVEL_INFO,
2736 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2737 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002738#ifdef WLAN_FEATURE_11AC
2739 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2740 {
2741 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2742 }
2743#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302744 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002745 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002746 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002747 //Check for sub-string p2p to confirm its a p2p interface
2748 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302749 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002750 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2751 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2752 }
2753 else
2754 {
2755 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002757 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302758#ifdef FEATURE_WLAN_TDLS
2759 /* The open adapter for the p2p shall skip initializations in
2760 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2761 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2762 * tdls_init when the change_iface sets the device mode to
2763 * WLAN_HDD_P2P_CLIENT.
2764 */
2765
2766 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2767 {
2768 if (0 != wlan_hdd_tdls_init (pAdapter))
2769 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302770 hddLog(VOS_TRACE_LEVEL_ERROR,
2771 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302772 return -EINVAL;
2773 }
2774 }
2775#endif
2776
Jeff Johnson295189b2012-06-20 16:38:30 -07002777 break;
2778 case NL80211_IFTYPE_ADHOC:
2779 hddLog(VOS_TRACE_LEVEL_INFO,
2780 "%s: setting interface Type to ADHOC", __func__);
2781 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2782 pRoamProfile->phyMode =
2783 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002784 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002785 wdev->iftype = type;
2786 break;
2787
2788 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002789 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002790 {
2791 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2792 "%s: setting interface Type to %s", __func__,
2793 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2794
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002795 //Cancel any remain on channel for GO mode
2796 if (NL80211_IFTYPE_P2P_GO == type)
2797 {
2798 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2799 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002800 if (NL80211_IFTYPE_AP == type)
2801 {
2802 /* As Loading WLAN Driver one interface being created for p2p device
2803 * address. This will take one HW STA and the max number of clients
2804 * that can connect to softAP will be reduced by one. so while changing
2805 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2806 * interface as it is not required in SoftAP mode.
2807 */
2808
2809 // Get P2P Adapter
2810 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2811
2812 if (pP2pAdapter)
2813 {
2814 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2815 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2816 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2817 }
2818 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302819#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002820
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302821 /* A Mutex Lock is introduced while changing the mode to
2822 * protect the concurrent access for the Adapters by TDLS
2823 * module.
2824 */
2825 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2826 {
2827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: unable to lock list", __func__);
2829 return -EINVAL;
2830 }
2831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002832 //De-init the adapter.
2833 hdd_stop_adapter( pHddCtx, pAdapter );
2834 hdd_deinit_adapter( pHddCtx, pAdapter );
2835 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2837 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302838#ifdef FEATURE_WLAN_TDLS
2839 mutex_unlock(&pHddCtx->tdls_lock);
2840#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002841
2842 //Disable BMPS and IMPS if enabled
2843 //before starting Go
2844 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302846 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002847 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2848 {
2849 //Fail to Exit BMPS
2850 VOS_ASSERT(0);
2851 }
2852 }
2853
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002854 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2855 (pConfig->apRandomBssidEnabled))
2856 {
2857 /* To meet Android requirements create a randomized
2858 MAC address of the form 02:1A:11:Fx:xx:xx */
2859 get_random_bytes(&ndev->dev_addr[3], 3);
2860 ndev->dev_addr[0] = 0x02;
2861 ndev->dev_addr[1] = 0x1A;
2862 ndev->dev_addr[2] = 0x11;
2863 ndev->dev_addr[3] |= 0xF0;
2864 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2865 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002866 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2867 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002868 }
2869
Jeff Johnson295189b2012-06-20 16:38:30 -07002870 hdd_set_ap_ops( pAdapter->dev );
2871
Kiet Lam10841362013-11-01 11:36:50 +05302872 /* This is for only SAP mode where users can
2873 * control country through ini.
2874 * P2P GO follows station country code
2875 * acquired during the STA scanning. */
2876 if((NL80211_IFTYPE_AP == type) &&
2877 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2878 {
2879 int status = 0;
2880 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2881 "%s: setting country code from INI ", __func__);
2882 init_completion(&pAdapter->change_country_code);
2883 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2884 (void *)(tSmeChangeCountryCallback)
2885 wlan_hdd_change_country_code_cb,
2886 pConfig->apCntryCode, pAdapter,
2887 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302888 eSIR_FALSE,
2889 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302890 if (eHAL_STATUS_SUCCESS == status)
2891 {
2892 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302893 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302894 &pAdapter->change_country_code,
2895 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302896 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05302897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302899 FL("SME Timed out while setting country code %ld"),
2900 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002901
2902 if (pHddCtx->isLogpInProgress)
2903 {
2904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2905 "%s: LOGP in Progress. Ignore!!!", __func__);
2906 return -EAGAIN;
2907 }
Kiet Lam10841362013-11-01 11:36:50 +05302908 }
2909 }
2910 else
2911 {
2912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002913 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05302914 return -EINVAL;
2915 }
2916 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002917 status = hdd_init_ap_mode(pAdapter);
2918 if(status != VOS_STATUS_SUCCESS)
2919 {
2920 hddLog(VOS_TRACE_LEVEL_FATAL,
2921 "%s: Error initializing the ap mode", __func__);
2922 return -EINVAL;
2923 }
2924 hdd_set_conparam(1);
2925
Jeff Johnson295189b2012-06-20 16:38:30 -07002926 /*interface type changed update in wiphy structure*/
2927 if(wdev)
2928 {
2929 wdev->iftype = type;
2930 pHddCtx->change_iface = type;
2931 }
2932 else
2933 {
2934 hddLog(VOS_TRACE_LEVEL_ERROR,
2935 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2936 return -EINVAL;
2937 }
2938 goto done;
2939 }
2940
2941 default:
2942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2943 __func__);
2944 return -EOPNOTSUPP;
2945 }
2946 }
2947 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002949 )
2950 {
2951 switch(type)
2952 {
2953 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002954 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302956#ifdef FEATURE_WLAN_TDLS
2957
2958 /* A Mutex Lock is introduced while changing the mode to
2959 * protect the concurrent access for the Adapters by TDLS
2960 * module.
2961 */
2962 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2963 {
2964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2965 "%s: unable to lock list", __func__);
2966 return -EINVAL;
2967 }
2968#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002969 hdd_stop_adapter( pHddCtx, pAdapter );
2970 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002971 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002972 //Check for sub-string p2p to confirm its a p2p interface
2973 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002974 {
2975 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2976 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2977 }
2978 else
2979 {
2980 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 hdd_set_conparam(0);
2984 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002985 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2986 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302987#ifdef FEATURE_WLAN_TDLS
2988 mutex_unlock(&pHddCtx->tdls_lock);
2989#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05302990 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 if( VOS_STATUS_SUCCESS != status )
2992 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002993 /* In case of JB, for P2P-GO, only change interface will be called,
2994 * This is the right place to enable back bmps_imps()
2995 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302996 if (pHddCtx->hdd_wlan_suspended)
2997 {
2998 hdd_set_pwrparams(pHddCtx);
2999 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003000 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003001 goto done;
3002 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003003 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003004 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003005 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3006 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003007 goto done;
3008 default:
3009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3010 __func__);
3011 return -EOPNOTSUPP;
3012
3013 }
3014
3015 }
3016 else
3017 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303018 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3019 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003020 return -EOPNOTSUPP;
3021 }
3022
3023
3024 if(pRoamProfile)
3025 {
3026 if ( LastBSSType != pRoamProfile->BSSType )
3027 {
3028 /*interface type changed update in wiphy structure*/
3029 wdev->iftype = type;
3030
3031 /*the BSS mode changed, We need to issue disconnect
3032 if connected or in IBSS disconnect state*/
3033 if ( hdd_connGetConnectedBssType(
3034 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3035 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3036 {
3037 /*need to issue a disconnect to CSR.*/
3038 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3039 if( eHAL_STATUS_SUCCESS ==
3040 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3041 pAdapter->sessionId,
3042 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3043 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303044 ret = wait_for_completion_interruptible_timeout(
3045 &pAdapter->disconnect_comp_var,
3046 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3047 if (ret <= 0)
3048 {
3049 hddLog(VOS_TRACE_LEVEL_ERROR,
3050 FL("wait on disconnect_comp_var failed %ld"), ret);
3051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003052 }
3053 }
3054 }
3055 }
3056
3057done:
3058 /*set bitmask based on updated value*/
3059 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003060
3061 /* Only STA mode support TM now
3062 * all other mode, TM feature should be disabled */
3063 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3064 (~VOS_STA & pHddCtx->concurrency_mode) )
3065 {
3066 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3067 }
3068
Jeff Johnson295189b2012-06-20 16:38:30 -07003069#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303070 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003071 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3072 {
3073 //we are ok to do AMP
3074 pHddCtx->isAmpAllowed = VOS_TRUE;
3075 }
3076#endif //WLAN_BTAMP_FEATURE
3077 EXIT();
3078 return 0;
3079}
3080
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003081#ifdef FEATURE_WLAN_TDLS
3082static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3083 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3084{
3085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3086 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3087 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003088 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303089 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003090
3091 ENTER();
3092
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303093 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003094 {
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "Invalid arguments");
3097 return -EINVAL;
3098 }
Hoonki Lee27511902013-03-14 18:19:06 -07003099
3100 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3101 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3102 {
3103 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3104 "%s: TDLS mode is disabled OR not enabled in FW."
3105 MAC_ADDRESS_STR " Request declined.",
3106 __func__, MAC_ADDR_ARRAY(mac));
3107 return -ENOTSUPP;
3108 }
3109
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003110 if (pHddCtx->isLogpInProgress)
3111 {
3112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003114 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003115 return -EBUSY;
3116 }
3117
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303118 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003119
3120 if ( NULL == pTdlsPeer ) {
3121 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3122 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3123 __func__, MAC_ADDR_ARRAY(mac), update);
3124 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003125 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003126
3127 /* in add station, we accept existing valid staId if there is */
3128 if ((0 == update) &&
3129 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3130 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003131 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003132 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003133 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003134 " link_status %d. staId %d. add station ignored.",
3135 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3136 return 0;
3137 }
3138 /* in change station, we accept only when staId is valid */
3139 if ((1 == update) &&
3140 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3141 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3142 {
3143 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3144 "%s: " MAC_ADDRESS_STR
3145 " link status %d. staId %d. change station %s.",
3146 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3147 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3148 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003149 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003150
3151 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303152 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003153 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3155 "%s: " MAC_ADDRESS_STR
3156 " TDLS setup is ongoing. Request declined.",
3157 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003158 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003159 }
3160
3161 /* first to check if we reached to maximum supported TDLS peer.
3162 TODO: for now, return -EPERM looks working fine,
3163 but need to check if any other errno fit into this category.*/
3164 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3165 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3167 "%s: " MAC_ADDRESS_STR
3168 " TDLS Max peer already connected. Request declined.",
3169 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003170 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003171 }
3172 else
3173 {
3174 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303175 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003176 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003177 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3179 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3180 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003181 return -EPERM;
3182 }
3183 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003184 if (0 == update)
3185 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003186
Jeff Johnsond75fe012013-04-06 10:53:06 -07003187 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303188 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003189 {
3190 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3191 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003192 if(StaParams->htcap_present)
3193 {
3194 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3195 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3196 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3197 "ht_capa->extended_capabilities: %0x",
3198 StaParams->HTCap.extendedHtCapInfo);
3199 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003200 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3201 "params->capability: %0x",StaParams->capability);
3202 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003203 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003204 if(StaParams->vhtcap_present)
3205 {
3206 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3207 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3208 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3209 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3210 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003211 {
3212 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003214 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3215 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3216 "[%d]: %x ", i, StaParams->supported_rates[i]);
3217 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003218 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303219 else if ((1 == update) && (NULL == StaParams))
3220 {
3221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3222 "%s : update is true, but staParams is NULL. Error!", __func__);
3223 return -EPERM;
3224 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003225
3226 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3227
3228 if (!update)
3229 {
3230 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3231 pAdapter->sessionId, mac);
3232 }
3233 else
3234 {
3235 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3236 pAdapter->sessionId, mac, StaParams);
3237 }
3238
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303239 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003240 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3241
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303242 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003243 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303245 "%s: timeout waiting for tdls add station indication %ld",
3246 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003247 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003248 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303249
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003250 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3251 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003253 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003254 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003255 }
3256
3257 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003258
3259error:
3260 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3261 return -EPERM;
3262
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003263}
3264#endif
3265
Jeff Johnson295189b2012-06-20 16:38:30 -07003266static int wlan_hdd_change_station(struct wiphy *wiphy,
3267 struct net_device *dev,
3268 u8 *mac,
3269 struct station_parameters *params)
3270{
3271 VOS_STATUS status = VOS_STATUS_SUCCESS;
3272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303273 hdd_context_t *pHddCtx;
3274 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003276#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003277 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003278 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003279#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003280 ENTER();
3281
Gopichand Nakkala29149562013-05-10 21:43:41 +05303282 if ((NULL == pAdapter))
3283 {
3284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3285 "invalid adapter ");
3286 return -EINVAL;
3287 }
3288
3289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3291
3292 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3293 {
3294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3295 "invalid HDD state or HDD station context");
3296 return -EINVAL;
3297 }
3298
3299 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003300 {
3301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3302 "%s:LOGP in Progress. Ignore!!!", __func__);
3303 return -EAGAIN;
3304 }
3305
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3307
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003308 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3309 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003310 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003311 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303313 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003314 WLANTL_STA_AUTHENTICATED);
3315
Gopichand Nakkala29149562013-05-10 21:43:41 +05303316 if (status != VOS_STATUS_SUCCESS)
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3319 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3320 return -EINVAL;
3321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 }
3323 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003324 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3325 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303326#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003327 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3328 StaParams.capability = params->capability;
3329 StaParams.uapsd_queues = params->uapsd_queues;
3330 StaParams.max_sp = params->max_sp;
3331
3332 if (0 != params->ext_capab_len)
3333 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3334 sizeof(StaParams.extn_capability));
3335
3336 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003337 {
3338 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003339 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003340 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003341
3342 StaParams.supported_rates_len = params->supported_rates_len;
3343
3344 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3345 * The supported_rates array , for all the structures propogating till Add Sta
3346 * to the firmware has to be modified , if the supplicant (ieee80211) is
3347 * modified to send more rates.
3348 */
3349
3350 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3351 */
3352 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3353 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3354
3355 if (0 != StaParams.supported_rates_len) {
3356 int i = 0;
3357 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3358 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003360 "Supported Rates with Length %d", StaParams.supported_rates_len);
3361 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003363 "[%d]: %0x", i, StaParams.supported_rates[i]);
3364 }
3365
3366 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003367 {
3368 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003369 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003370 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003371
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003372 if (0 != params->ext_capab_len ) {
3373 /*Define A Macro : TODO Sunil*/
3374 if ((1<<4) & StaParams.extn_capability[3]) {
3375 isBufSta = 1;
3376 }
3377 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303378 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3379 params->max_sp, isBufSta);
3380 if (VOS_STATUS_SUCCESS != status) {
3381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3382 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3383 return -EINVAL;
3384 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003385 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3386
3387 if (VOS_STATUS_SUCCESS != status) {
3388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3389 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3390 return -EINVAL;
3391 }
3392 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003393#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303394 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003395 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003396 return status;
3397}
3398
3399/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003400 * FUNCTION: wlan_hdd_cfg80211_add_key
3401 * This function is used to initialize the key information
3402 */
3403#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003404static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003405 struct net_device *ndev,
3406 u8 key_index, bool pairwise,
3407 const u8 *mac_addr,
3408 struct key_params *params
3409 )
3410#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003411static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 struct net_device *ndev,
3413 u8 key_index, const u8 *mac_addr,
3414 struct key_params *params
3415 )
3416#endif
3417{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003419 tCsrRoamSetKey setKey;
3420 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303421 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003422 v_U32_t roamId= 0xFF;
3423 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003424 hdd_hostapd_state_t *pHostapdState;
3425 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003426 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303427 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003428
3429 ENTER();
3430
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3432 status = wlan_hdd_validate_context(pHddCtx);
3433
3434 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003435 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3437 "%s: HDD context is not valid", __func__);
3438 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003439 }
3440
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003441 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3442 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003443
3444 if (CSR_MAX_NUM_KEY <= key_index)
3445 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003447 key_index);
3448
3449 return -EINVAL;
3450 }
3451
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003452 if (CSR_MAX_KEY_LEN < params->key_len)
3453 {
3454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3455 params->key_len);
3456
3457 return -EINVAL;
3458 }
3459
3460 hddLog(VOS_TRACE_LEVEL_INFO,
3461 "%s: called with key index = %d & key length %d",
3462 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003463
3464 /*extract key idx, key len and key*/
3465 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3466 setKey.keyId = key_index;
3467 setKey.keyLength = params->key_len;
3468 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3469
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003470 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 {
3472 case WLAN_CIPHER_SUITE_WEP40:
3473 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3474 break;
3475
3476 case WLAN_CIPHER_SUITE_WEP104:
3477 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3478 break;
3479
3480 case WLAN_CIPHER_SUITE_TKIP:
3481 {
3482 u8 *pKey = &setKey.Key[0];
3483 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3484
3485 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3486
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003487 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003488
3489 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003490 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003491 |--------------|----------|----------|
3492 <---16bytes---><--8bytes--><--8bytes-->
3493
3494 */
3495 /*Sme expects the 32 bytes key to be in the below order
3496
3497 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003498 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003499 |--------------|----------|----------|
3500 <---16bytes---><--8bytes--><--8bytes-->
3501 */
3502 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003503 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003504
3505 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003506 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003507
3508 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003509 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003510
3511
3512 break;
3513 }
3514
3515 case WLAN_CIPHER_SUITE_CCMP:
3516 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3517 break;
3518
3519#ifdef FEATURE_WLAN_WAPI
3520 case WLAN_CIPHER_SUITE_SMS4:
3521 {
3522 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3523 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3524 params->key, params->key_len);
3525 return 0;
3526 }
3527#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003528
Jeff Johnson295189b2012-06-20 16:38:30 -07003529#ifdef FEATURE_WLAN_CCX
3530 case WLAN_CIPHER_SUITE_KRK:
3531 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3532 break;
3533#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003534
3535#ifdef WLAN_FEATURE_11W
3536 case WLAN_CIPHER_SUITE_AES_CMAC:
3537 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003538 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003539#endif
3540
Jeff Johnson295189b2012-06-20 16:38:30 -07003541 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003543 __func__, params->cipher);
3544 return -EOPNOTSUPP;
3545 }
3546
3547 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3548 __func__, setKey.encType);
3549
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003550 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3552 (!pairwise)
3553#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003554 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003555#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003556 )
3557 {
3558 /* set group key*/
3559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3560 "%s- %d: setting Broadcast key",
3561 __func__, __LINE__);
3562 setKey.keyDirection = eSIR_RX_ONLY;
3563 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3564 }
3565 else
3566 {
3567 /* set pairwise key*/
3568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3569 "%s- %d: setting pairwise key",
3570 __func__, __LINE__);
3571 setKey.keyDirection = eSIR_TX_RX;
3572 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3573 }
3574 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3575 {
3576 setKey.keyDirection = eSIR_TX_RX;
3577 /*Set the group key*/
3578 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3579 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003580
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003581 if ( 0 != status )
3582 {
3583 hddLog(VOS_TRACE_LEVEL_ERROR,
3584 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3585 return -EINVAL;
3586 }
3587 /*Save the keys here and call sme_RoamSetKey for setting
3588 the PTK after peer joins the IBSS network*/
3589 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3590 &setKey, sizeof(tCsrRoamSetKey));
3591 return status;
3592 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303593 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3594 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3595 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003597 if( pHostapdState->bssState == BSS_START )
3598 {
c_hpothu7c55da62014-01-23 18:34:02 +05303599 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3600 vos_status = wlan_hdd_check_ula_done(pAdapter);
3601
3602 if ( vos_status != VOS_STATUS_SUCCESS )
3603 {
3604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3605 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3606 __LINE__, vos_status );
3607
3608 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3609
3610 return -EINVAL;
3611 }
3612
Jeff Johnson295189b2012-06-20 16:38:30 -07003613 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3614
3615 if ( status != eHAL_STATUS_SUCCESS )
3616 {
3617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3618 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3619 __LINE__, status );
3620 }
3621 }
3622
3623 /* Saving WEP keys */
3624 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3625 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3626 {
3627 //Save the wep key in ap context. Issue setkey after the BSS is started.
3628 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3629 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3630 }
3631 else
3632 {
3633 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003634 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003635 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3636 }
3637 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003638 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3639 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003640 {
3641 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3642 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3643
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3645 if (!pairwise)
3646#else
3647 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3648#endif
3649 {
3650 /* set group key*/
3651 if (pHddStaCtx->roam_info.deferKeyComplete)
3652 {
3653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3654 "%s- %d: Perform Set key Complete",
3655 __func__, __LINE__);
3656 hdd_PerformRoamSetKeyComplete(pAdapter);
3657 }
3658 }
3659
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3661
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003662 pWextState->roamProfile.Keys.defaultIndex = key_index;
3663
3664
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003665 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003666 params->key, params->key_len);
3667
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303668
Jeff Johnson295189b2012-06-20 16:38:30 -07003669 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303671 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303673 __func__, setKey.peerMac[0], setKey.peerMac[1],
3674 setKey.peerMac[2], setKey.peerMac[3],
3675 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003676 setKey.keyDirection);
3677
3678 vos_status = wlan_hdd_check_ula_done(pAdapter);
3679
3680 if ( vos_status != VOS_STATUS_SUCCESS )
3681 {
3682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3684 __LINE__, vos_status );
3685
3686 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3687
3688 return -EINVAL;
3689
3690 }
3691
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003692#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303693 /* The supplicant may attempt to set the PTK once pre-authentication
3694 is done. Save the key in the UMAC and include it in the ADD BSS
3695 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003696 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303697 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003698 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303699 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3700 "%s: Update PreAuth Key success", __func__);
3701 return 0;
3702 }
3703 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3704 {
3705 hddLog(VOS_TRACE_LEVEL_ERROR,
3706 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303707 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003708 }
3709#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003710
3711 /* issue set key request to SME*/
3712 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3713 pAdapter->sessionId, &setKey, &roamId );
3714
3715 if ( 0 != status )
3716 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303717 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003718 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3719 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3720 return -EINVAL;
3721 }
3722
3723
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303724 /* in case of IBSS as there was no information available about WEP keys during
3725 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303727 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3728 !( ( IW_AUTH_KEY_MGMT_802_1X
3729 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3731 )
3732 &&
3733 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3734 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3735 )
3736 )
3737 {
3738 setKey.keyDirection = eSIR_RX_ONLY;
3739 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303741 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003742 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303743 __func__, setKey.peerMac[0], setKey.peerMac[1],
3744 setKey.peerMac[2], setKey.peerMac[3],
3745 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003746 setKey.keyDirection);
3747
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303748 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003749 pAdapter->sessionId, &setKey, &roamId );
3750
3751 if ( 0 != status )
3752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303753 hddLog(VOS_TRACE_LEVEL_ERROR,
3754 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003755 __func__, status);
3756 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3757 return -EINVAL;
3758 }
3759 }
3760 }
3761
3762 return 0;
3763}
3764
3765/*
3766 * FUNCTION: wlan_hdd_cfg80211_get_key
3767 * This function is used to get the key information
3768 */
3769#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303770static int wlan_hdd_cfg80211_get_key(
3771 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003772 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303773 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003774 const u8 *mac_addr, void *cookie,
3775 void (*callback)(void *cookie, struct key_params*)
3776 )
3777#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303778static int wlan_hdd_cfg80211_get_key(
3779 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003780 struct net_device *ndev,
3781 u8 key_index, const u8 *mac_addr, void *cookie,
3782 void (*callback)(void *cookie, struct key_params*)
3783 )
3784#endif
3785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003787 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3788 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3789 struct key_params params;
3790
3791 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303792
Arif Hussain6d2a3322013-11-17 19:50:10 -08003793 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003794 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303795
Jeff Johnson295189b2012-06-20 16:38:30 -07003796 memset(&params, 0, sizeof(params));
3797
3798 if (CSR_MAX_NUM_KEY <= key_index)
3799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003801 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003803
3804 switch(pRoamProfile->EncryptionType.encryptionType[0])
3805 {
3806 case eCSR_ENCRYPT_TYPE_NONE:
3807 params.cipher = IW_AUTH_CIPHER_NONE;
3808 break;
3809
3810 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3811 case eCSR_ENCRYPT_TYPE_WEP40:
3812 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3813 break;
3814
3815 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3816 case eCSR_ENCRYPT_TYPE_WEP104:
3817 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3818 break;
3819
3820 case eCSR_ENCRYPT_TYPE_TKIP:
3821 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3822 break;
3823
3824 case eCSR_ENCRYPT_TYPE_AES:
3825 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3826 break;
3827
3828 default:
3829 params.cipher = IW_AUTH_CIPHER_NONE;
3830 break;
3831 }
3832
3833 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3834 params.seq_len = 0;
3835 params.seq = NULL;
3836 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3837 callback(cookie, &params);
3838 return 0;
3839}
3840
3841/*
3842 * FUNCTION: wlan_hdd_cfg80211_del_key
3843 * This function is used to delete the key information
3844 */
3845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303846static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003847 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303848 u8 key_index,
3849 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003850 const u8 *mac_addr
3851 )
3852#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303853static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003854 struct net_device *ndev,
3855 u8 key_index,
3856 const u8 *mac_addr
3857 )
3858#endif
3859{
3860 int status = 0;
3861
3862 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303863 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003864 //it is observed that this is invalidating peer
3865 //key index whenever re-key is done. This is affecting data link.
3866 //It should be ok to ignore del_key.
3867#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303868 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3869 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3871 tCsrRoamSetKey setKey;
3872 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303873
Jeff Johnson295189b2012-06-20 16:38:30 -07003874 ENTER();
3875
3876 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3877 __func__,pAdapter->device_mode);
3878
3879 if (CSR_MAX_NUM_KEY <= key_index)
3880 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003882 key_index);
3883
3884 return -EINVAL;
3885 }
3886
3887 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3888 setKey.keyId = key_index;
3889
3890 if (mac_addr)
3891 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3892 else
3893 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3894
3895 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3896
3897 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003898 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303899 )
3900 {
3901
3902 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3904 if( pHostapdState->bssState == BSS_START)
3905 {
3906 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303907
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 if ( status != eHAL_STATUS_SUCCESS )
3909 {
3910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3911 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3912 __LINE__, status );
3913 }
3914 }
3915 }
3916 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303917 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003918 )
3919 {
3920 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3921
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303922 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3923
3924 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003925 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303926 __func__, setKey.peerMac[0], setKey.peerMac[1],
3927 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303929 if(pAdapter->sessionCtx.station.conn_info.connState ==
3930 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003931 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303934
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 if ( 0 != status )
3936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303937 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 "%s: sme_RoamSetKey failure, returned %d",
3939 __func__, status);
3940 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3941 return -EINVAL;
3942 }
3943 }
3944 }
3945#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003946 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003947 return status;
3948}
3949
3950/*
3951 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3952 * This function is used to set the default tx key index
3953 */
3954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3955static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3956 struct net_device *ndev,
3957 u8 key_index,
3958 bool unicast, bool multicast)
3959#else
3960static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3961 struct net_device *ndev,
3962 u8 key_index)
3963#endif
3964{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303965 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303966 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303967 hdd_wext_state_t *pWextState;
3968 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303969 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003970
3971 ENTER();
3972
Gopichand Nakkala29149562013-05-10 21:43:41 +05303973 if ((NULL == pAdapter))
3974 {
3975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3976 "invalid adapter");
3977 return -EINVAL;
3978 }
3979
3980 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3981 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3982
3983 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3984 {
3985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3986 "invalid Wext state or HDD context");
3987 return -EINVAL;
3988 }
3989
Arif Hussain6d2a3322013-11-17 19:50:10 -08003990 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303992
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 if (CSR_MAX_NUM_KEY <= key_index)
3994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003996 key_index);
3997
3998 return -EINVAL;
3999 }
4000
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4002 status = wlan_hdd_validate_context(pHddCtx);
4003
4004 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004005 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4007 "%s: HDD context is not valid", __func__);
4008 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004009 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304010
Jeff Johnson295189b2012-06-20 16:38:30 -07004011 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004012 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304013 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004014 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304015 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004016 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304017 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004018 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004019 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304020 {
4021 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004022 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023
Jeff Johnson295189b2012-06-20 16:38:30 -07004024 tCsrRoamSetKey setKey;
4025 v_U32_t roamId= 0xFF;
4026 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304027
4028 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004029 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304030
Jeff Johnson295189b2012-06-20 16:38:30 -07004031 Keys->defaultIndex = (u8)key_index;
4032 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4033 setKey.keyId = key_index;
4034 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304035
4036 vos_mem_copy(&setKey.Key[0],
4037 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304039
Gopichand Nakkala29149562013-05-10 21:43:41 +05304040 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041
4042 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004043 &pHddStaCtx->conn_info.bssId[0],
4044 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304045
Gopichand Nakkala29149562013-05-10 21:43:41 +05304046 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4047 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4048 eCSR_ENCRYPT_TYPE_WEP104)
4049 {
4050 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4051 even though ap is configured for WEP-40 encryption. In this canse the key length
4052 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4053 type(104) and switching encryption type to 40*/
4054 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4055 eCSR_ENCRYPT_TYPE_WEP40;
4056 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4057 eCSR_ENCRYPT_TYPE_WEP40;
4058 }
4059
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304060 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004061 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304062
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004065 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304066
Jeff Johnson295189b2012-06-20 16:38:30 -07004067 if ( 0 != status )
4068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304069 hddLog(VOS_TRACE_LEVEL_ERROR,
4070 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004071 status);
4072 return -EINVAL;
4073 }
4074 }
4075 }
4076
4077 /* In SoftAp mode setting key direction for default mode */
4078 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4079 {
4080 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4081 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4082 (eCSR_ENCRYPT_TYPE_AES !=
4083 pWextState->roamProfile.EncryptionType.encryptionType[0])
4084 )
4085 {
4086 /* Saving key direction for default key index to TX default */
4087 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4088 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4089 }
4090 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304091
Jeff Johnson295189b2012-06-20 16:38:30 -07004092 return status;
4093}
4094
Jeff Johnson295189b2012-06-20 16:38:30 -07004095/*
4096 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4097 * This function is used to inform the BSS details to nl80211 interface.
4098 */
4099static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4100 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4101{
4102 struct net_device *dev = pAdapter->dev;
4103 struct wireless_dev *wdev = dev->ieee80211_ptr;
4104 struct wiphy *wiphy = wdev->wiphy;
4105 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4106 int chan_no;
4107 int ie_length;
4108 const char *ie;
4109 unsigned int freq;
4110 struct ieee80211_channel *chan;
4111 int rssi = 0;
4112 struct cfg80211_bss *bss = NULL;
4113
4114 ENTER();
4115
4116 if( NULL == pBssDesc )
4117 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004118 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004119 return bss;
4120 }
4121
4122 chan_no = pBssDesc->channelId;
4123 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4124 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4125
4126 if( NULL == ie )
4127 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004128 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004129 return bss;
4130 }
4131
4132#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4133 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4134 {
4135 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4136 }
4137 else
4138 {
4139 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4140 }
4141#else
4142 freq = ieee80211_channel_to_frequency(chan_no);
4143#endif
4144
4145 chan = __ieee80211_get_channel(wiphy, freq);
4146
4147 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4148 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4149 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4150 if (bss == NULL)
4151 {
4152 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4153
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304154 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4155 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 pBssDesc->capabilityInfo,
4157 pBssDesc->beaconInterval, ie, ie_length,
4158 rssi, GFP_KERNEL ));
4159}
4160 else
4161 {
4162 return bss;
4163 }
4164}
4165
4166
4167
4168/*
4169 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4170 * This function is used to inform the BSS details to nl80211 interface.
4171 */
4172struct cfg80211_bss*
4173wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4174 tSirBssDescription *bss_desc
4175 )
4176{
4177 /*
4178 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4179 already exists in bss data base of cfg80211 for that particular BSS ID.
4180 Using cfg80211_inform_bss_frame to update the bss entry instead of
4181 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4182 now there is no possibility to get the mgmt(probe response) frame from PE,
4183 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4184 cfg80211_inform_bss_frame.
4185 */
4186 struct net_device *dev = pAdapter->dev;
4187 struct wireless_dev *wdev = dev->ieee80211_ptr;
4188 struct wiphy *wiphy = wdev->wiphy;
4189 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004190#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4191 qcom_ie_age *qie_age = NULL;
4192 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4193#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004194 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004195#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004196 const char *ie =
4197 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4198 unsigned int freq;
4199 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304200 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 struct cfg80211_bss *bss_status = NULL;
4202 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4203 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004204 hdd_context_t *pHddCtx;
4205 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004206#ifdef WLAN_OPEN_SOURCE
4207 struct timespec ts;
4208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004209
4210 ENTER();
4211
Wilson Yangf80a0542013-10-07 13:02:37 -07004212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4213 status = wlan_hdd_validate_context(pHddCtx);
4214
4215 /*bss_update is not allowed during wlan driver loading or unloading*/
4216 if (pHddCtx->isLoadUnloadInProgress)
4217 {
4218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4219 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4220 return NULL;
4221 }
4222
4223
4224 if (0 != status)
4225 {
4226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4227 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004228 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004229 }
4230
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304231 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004232 if (!mgmt)
4233 {
4234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4235 "%s: memory allocation failed ", __func__);
4236 return NULL;
4237 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004238
Jeff Johnson295189b2012-06-20 16:38:30 -07004239 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004240
4241#ifdef WLAN_OPEN_SOURCE
4242 /* Android does not want the timestamp from the frame.
4243 Instead it wants a monotonic increasing value */
4244 get_monotonic_boottime(&ts);
4245 mgmt->u.probe_resp.timestamp =
4246 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4247#else
4248 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4250 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004251
4252#endif
4253
Jeff Johnson295189b2012-06-20 16:38:30 -07004254 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4255 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004256
4257#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4258 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4259 /* Assuming this is the last IE, copy at the end */
4260 ie_length -=sizeof(qcom_ie_age);
4261 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4262 qie_age->element_id = QCOM_VENDOR_IE_ID;
4263 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4264 qie_age->oui_1 = QCOM_OUI1;
4265 qie_age->oui_2 = QCOM_OUI2;
4266 qie_age->oui_3 = QCOM_OUI3;
4267 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4268 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4269#endif
4270
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304272 if (bss_desc->fProbeRsp)
4273 {
4274 mgmt->frame_control |=
4275 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4276 }
4277 else
4278 {
4279 mgmt->frame_control |=
4280 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004282
4283#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004285 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4286 {
4287 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4288 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304289 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004290 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4291
4292 {
4293 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4294 }
4295 else
4296 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4298 "%s: invalid chan_no %d", __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004299 kfree(mgmt);
4300 return NULL;
4301 }
4302#else
4303 freq = ieee80211_channel_to_frequency(chan_no);
4304#endif
4305 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004306 /*when the band is changed on the fly using the GUI, three things are done
4307 * 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)
4308 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4309 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4310 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4311 * and discards the channels correponding to previous band and calls back with zero bss results.
4312 * 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
4313 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4314 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4315 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4316 * So drop the bss and continue to next bss.
4317 */
4318 if(chan == NULL)
4319 {
4320 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004321 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004322 return NULL;
4323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004324 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304325 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 * */
4327 if (( eConnectionState_Associated ==
4328 pAdapter->sessionCtx.station.conn_info.connState ) &&
4329 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4330 pAdapter->sessionCtx.station.conn_info.bssId,
4331 WNI_CFG_BSSID_LEN)))
4332 {
4333 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4334 rssi = (pAdapter->rssi * 100);
4335 }
4336 else
4337 {
4338 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4339 }
4340
4341 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4342 frame_len, rssi, GFP_KERNEL);
4343 kfree(mgmt);
4344 return bss_status;
4345}
4346
4347/*
4348 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4349 * This function is used to update the BSS data base of CFG8011
4350 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304351struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004352 tCsrRoamInfo *pRoamInfo
4353 )
4354{
4355 tCsrRoamConnectedProfile roamProfile;
4356 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4357 struct cfg80211_bss *bss = NULL;
4358
4359 ENTER();
4360
4361 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4362 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4363
4364 if (NULL != roamProfile.pBssDesc)
4365 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304366 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004367 &roamProfile);
4368
4369 if (NULL == bss)
4370 {
4371 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4372 __func__);
4373 }
4374
4375 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4376 }
4377 else
4378 {
4379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4380 __func__);
4381 }
4382 return bss;
4383}
4384
4385/*
4386 * FUNCTION: wlan_hdd_cfg80211_update_bss
4387 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304388static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4389 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004390 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304391{
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4393 tCsrScanResultInfo *pScanResult;
4394 eHalStatus status = 0;
4395 tScanResultHandle pResult;
4396 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004397 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004398
4399 ENTER();
4400
Wilson Yangf80a0542013-10-07 13:02:37 -07004401 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4402
4403 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004404 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4406 "%s:LOGP in Progress. Ignore!!!",__func__);
4407 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004408 }
4409
Wilson Yangf80a0542013-10-07 13:02:37 -07004410
4411 /*bss_update is not allowed during wlan driver loading or unloading*/
4412 if (pHddCtx->isLoadUnloadInProgress)
4413 {
4414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4415 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4416 return VOS_STATUS_E_PERM;
4417 }
4418
4419
Jeff Johnson295189b2012-06-20 16:38:30 -07004420 /*
4421 * start getting scan results and populate cgf80211 BSS database
4422 */
4423 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4424
4425 /* no scan results */
4426 if (NULL == pResult)
4427 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004429 return status;
4430 }
4431
4432 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4433
4434 while (pScanResult)
4435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304436 /*
4437 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4438 * entry already exists in bss data base of cfg80211 for that
4439 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4440 * bss entry instead of cfg80211_inform_bss, But this call expects
4441 * mgmt packet as input. As of now there is no possibility to get
4442 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004443 * ieee80211_mgmt(probe response) and passing to c
4444 * fg80211_inform_bss_frame.
4445 * */
4446
4447 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4448 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304449
Jeff Johnson295189b2012-06-20 16:38:30 -07004450
4451 if (NULL == bss_status)
4452 {
4453 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004454 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 }
4456 else
4457 {
Yue Maf49ba872013-08-19 12:04:25 -07004458 cfg80211_put_bss(
4459#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4460 wiphy,
4461#endif
4462 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 }
4464
4465 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4466 }
4467
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304468 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004469
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304470 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004471}
4472
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004473void
4474hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4475{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304476 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004477 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004478} /****** end hddPrintMacAddr() ******/
4479
4480void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004481hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004482{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304483 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004484 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004485 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4486 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4487 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004488} /****** end hddPrintPmkId() ******/
4489
4490//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4491//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4492
4493//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4494//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4495
4496#define dump_bssid(bssid) \
4497 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004498 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4499 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004500 }
4501
4502#define dump_pmkid(pMac, pmkid) \
4503 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004504 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4505 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004506 }
4507
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004508#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004509/*
4510 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4511 * This function is used to notify the supplicant of a new PMKSA candidate.
4512 */
4513int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304514 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004515 int index, bool preauth )
4516{
Jeff Johnsone7245742012-09-05 17:12:55 -07004517#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004518 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004519 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004520
4521 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004522 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004523
4524 if( NULL == pRoamInfo )
4525 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004526 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004527 return -EINVAL;
4528 }
4529
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004530 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4531 {
4532 dump_bssid(pRoamInfo->bssid);
4533 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004534 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004535 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004536#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304537 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004538}
4539#endif //FEATURE_WLAN_LFR
4540
Yue Maef608272013-04-08 23:09:17 -07004541#ifdef FEATURE_WLAN_LFR_METRICS
4542/*
4543 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4544 * 802.11r/LFR metrics reporting function to report preauth initiation
4545 *
4546 */
4547#define MAX_LFR_METRICS_EVENT_LENGTH 100
4548VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4549 tCsrRoamInfo *pRoamInfo)
4550{
4551 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4552 union iwreq_data wrqu;
4553
4554 ENTER();
4555
4556 if (NULL == pAdapter)
4557 {
4558 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4559 return VOS_STATUS_E_FAILURE;
4560 }
4561
4562 /* create the event */
4563 memset(&wrqu, 0, sizeof(wrqu));
4564 memset(metrics_notification, 0, sizeof(metrics_notification));
4565
4566 wrqu.data.pointer = metrics_notification;
4567 wrqu.data.length = scnprintf(metrics_notification,
4568 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4569 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4570
4571 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4572
4573 EXIT();
4574
4575 return VOS_STATUS_SUCCESS;
4576}
4577
4578/*
4579 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4580 * 802.11r/LFR metrics reporting function to report preauth completion
4581 * or failure
4582 */
4583VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4584 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4585{
4586 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4587 union iwreq_data wrqu;
4588
4589 ENTER();
4590
4591 if (NULL == pAdapter)
4592 {
4593 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4594 return VOS_STATUS_E_FAILURE;
4595 }
4596
4597 /* create the event */
4598 memset(&wrqu, 0, sizeof(wrqu));
4599 memset(metrics_notification, 0, sizeof(metrics_notification));
4600
4601 scnprintf(metrics_notification, sizeof(metrics_notification),
4602 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4603 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4604
4605 if (1 == preauth_status)
4606 strncat(metrics_notification, " TRUE", 5);
4607 else
4608 strncat(metrics_notification, " FALSE", 6);
4609
4610 wrqu.data.pointer = metrics_notification;
4611 wrqu.data.length = strlen(metrics_notification);
4612
4613 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4614
4615 EXIT();
4616
4617 return VOS_STATUS_SUCCESS;
4618}
4619
4620/*
4621 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4622 * 802.11r/LFR metrics reporting function to report handover initiation
4623 *
4624 */
4625VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4626 tCsrRoamInfo *pRoamInfo)
4627{
4628 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4629 union iwreq_data wrqu;
4630
4631 ENTER();
4632
4633 if (NULL == pAdapter)
4634 {
4635 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4636 return VOS_STATUS_E_FAILURE;
4637 }
4638
4639 /* create the event */
4640 memset(&wrqu, 0, sizeof(wrqu));
4641 memset(metrics_notification, 0, sizeof(metrics_notification));
4642
4643 wrqu.data.pointer = metrics_notification;
4644 wrqu.data.length = scnprintf(metrics_notification,
4645 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4646 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4647
4648 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4649
4650 EXIT();
4651
4652 return VOS_STATUS_SUCCESS;
4653}
4654#endif
4655
Jeff Johnson295189b2012-06-20 16:38:30 -07004656/*
4657 * FUNCTION: hdd_cfg80211_scan_done_callback
4658 * scanning callback function, called after finishing scan
4659 *
4660 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304661static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004662 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4663{
4664 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304665 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4668 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004669 struct cfg80211_scan_request *req = NULL;
4670 int ret = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304671 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004672
4673 ENTER();
4674
4675 hddLog(VOS_TRACE_LEVEL_INFO,
4676 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004677 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 __func__, halHandle, pContext, (int) scanId, (int) status);
4679
Kiet Lamac06e2c2013-10-23 16:25:07 +05304680 pScanInfo->mScanPendingCounter = 0;
4681
Jeff Johnson295189b2012-06-20 16:38:30 -07004682 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304683 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004684 &pScanInfo->scan_req_completion_event,
4685 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304686 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004687 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304688 hddLog(VOS_TRACE_LEVEL_ERROR,
4689 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004690 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004691 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 }
4693
Yue Maef608272013-04-08 23:09:17 -07004694 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 {
4696 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004697 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004698 }
4699
4700 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304701 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004702 {
4703 hddLog(VOS_TRACE_LEVEL_INFO,
4704 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004705 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004706 (int) scanId);
4707 }
4708
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304709 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004710 pAdapter);
4711
4712 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004714
4715
4716 /* If any client wait scan result through WEXT
4717 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004718 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004719 {
4720 /* The other scan request waiting for current scan finish
4721 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004722 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004723 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004724 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004725 }
4726 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004727 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004728 {
4729 struct net_device *dev = pAdapter->dev;
4730 union iwreq_data wrqu;
4731 int we_event;
4732 char *msg;
4733
4734 memset(&wrqu, '\0', sizeof(wrqu));
4735 we_event = SIOCGIWSCAN;
4736 msg = NULL;
4737 wireless_send_event(dev, we_event, &wrqu, msg);
4738 }
4739 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004740 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004741
4742 /* Get the Scan Req */
4743 req = pAdapter->request;
4744
4745 if (!req)
4746 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004747 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004748 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004749 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 }
4751
4752 /*
4753 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304754 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004755 req->n_ssids = 0;
4756 req->n_channels = 0;
4757 req->ie = 0;
4758
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004760 /* Scan is no longer pending */
4761 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004762
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004763 /*
4764 * cfg80211_scan_done informing NL80211 about completion
4765 * of scanning
4766 */
4767 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004768 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004769
Jeff Johnsone7245742012-09-05 17:12:55 -07004770allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004771 /* release the wake lock at the end of the scan*/
4772 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004773
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004774 /* Acquire wakelock to handle the case where APP's tries to suspend
4775 * immediatly after the driver gets connect request(i.e after scan)
4776 * from supplicant, this result in app's is suspending and not able
4777 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304778 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004779
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004780#ifdef FEATURE_WLAN_TDLS
4781 wlan_hdd_tdls_scan_done_callback(pAdapter);
4782#endif
4783
Jeff Johnson295189b2012-06-20 16:38:30 -07004784 EXIT();
4785 return 0;
4786}
4787
4788/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004789 * FUNCTION: hdd_isScanAllowed
4790 * Go through each adapter and check if scan allowed
4791 *
4792 */
4793v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4794{
4795 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4796 hdd_station_ctx_t *pHddStaCtx = NULL;
4797 hdd_adapter_t *pAdapter = NULL;
4798 VOS_STATUS status = 0;
4799 v_U8_t staId = 0;
4800 v_U8_t *staMac = NULL;
4801
c_hpothu9b781ba2013-12-30 20:57:45 +05304802 if (TRUE == pHddCtx->btCoexModeSet)
4803 {
4804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4805 FL("BTCoex Mode operation in progress, Do not allow scan"));
4806 return VOS_FALSE;
4807 }
4808
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004809 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4810
4811 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4812 {
4813 pAdapter = pAdapterNode->pAdapter;
4814
4815 if( pAdapter )
4816 {
4817 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304818 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004819 __func__, pAdapter->device_mode);
4820 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4821 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4822 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4823 {
4824 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4825 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4826 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4827 {
4828 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4829 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004830 "%s: client " MAC_ADDRESS_STR
4831 " is in the middle of WPS/EAPOL exchange.", __func__,
4832 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004833 return VOS_FALSE;
4834 }
4835 }
4836 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4837 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4838 {
4839 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304841 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004842 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4843 {
4844 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4845
4846 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004847 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4848 "middle of WPS/EAPOL exchange.", __func__,
4849 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004850 return VOS_FALSE;
4851 }
4852 }
4853 }
4854 }
4855 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4856 pAdapterNode = pNext;
4857 }
4858 hddLog(VOS_TRACE_LEVEL_INFO,
4859 "%s: Scan allowed", __func__);
4860 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304861}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004862
4863/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 * FUNCTION: wlan_hdd_cfg80211_scan
4865 * this scan respond to scan trigger and update cfg80211 scan database
4866 * later, scan dump command can be used to recieve scan results
4867 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004868int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4869#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4870 struct net_device *dev,
4871#endif
4872 struct cfg80211_scan_request *request)
4873{
4874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4875 struct net_device *dev = request->wdev->netdev;
4876#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004878 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4879 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304880 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 tCsrScanRequest scanRequest;
4882 tANI_U8 *channelList = NULL, i;
4883 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304884 int status;
4885 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004886 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004887
4888 ENTER();
4889
Arif Hussain6d2a3322013-11-17 19:50:10 -08004890 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004891 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004892
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304893 status = wlan_hdd_validate_context(pHddCtx);
4894
4895 if (0 != status)
4896 {
4897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4898 "%s: HDD context is not valid", __func__);
4899 return status;
4900 }
4901
4902 cfg_param = pHddCtx->cfg_ini;
4903 pScanInfo = &pHddCtx->scan_info;
4904
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004905 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004906 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004907 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004908 {
4909 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004910 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4911 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004912 return -EBUSY;
4913 }
4914
Jeff Johnson295189b2012-06-20 16:38:30 -07004915#ifdef WLAN_BTAMP_FEATURE
4916 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004917 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004918 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004919 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 "%s: No scanning when AMP is on", __func__);
4921 return -EOPNOTSUPP;
4922 }
4923#endif
4924 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004925 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004926 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004927 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 "%s: Not scanning on device_mode = %d",
4929 __func__, pAdapter->device_mode);
4930 return -EOPNOTSUPP;
4931 }
4932
4933 if (TRUE == pScanInfo->mScanPending)
4934 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05304935 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
4936 {
4937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
4938 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004939 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 }
4941
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304942 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004943 //Channel and action frame is pending
4944 //Otherwise Cancel Remain On Channel and allow Scan
4945 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004946 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004947 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05304948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004949 return -EBUSY;
4950 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004951#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004952 /* if tdls disagree scan right now, return immediately.
4953 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4954 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4955 */
4956 status = wlan_hdd_tdls_scan_callback (pAdapter,
4957 wiphy,
4958#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4959 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004960#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004961 request);
4962 if(status <= 0)
4963 {
4964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4965 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004966 }
4967#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004968
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4970 {
4971 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004972 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004975 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4976 {
4977 hddLog(VOS_TRACE_LEVEL_WARN,
4978 "%s: MAX TM Level Scan not allowed", __func__);
4979 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304980 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 }
4982 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4983
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004984 /* Check if scan is allowed at this point of time.
4985 */
4986 if (!hdd_isScanAllowed(pHddCtx))
4987 {
4988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4989 return -EBUSY;
4990 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304991
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4993
4994 if (NULL != request)
4995 {
4996 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304997 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004998
4999 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5000 * Becasue of this, driver is assuming that this is not wildcard scan and so
5001 * is not aging out the scan results.
5002 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005003 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 {
5005 request->n_ssids = 0;
5006 }
5007
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005008 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005009 {
5010 tCsrSSIDInfo *SsidInfo;
5011 int j;
5012 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5013 /* Allocate num_ssid tCsrSSIDInfo structure */
5014 SsidInfo = scanRequest.SSIDs.SSIDList =
5015 ( tCsrSSIDInfo *)vos_mem_malloc(
5016 request->n_ssids*sizeof(tCsrSSIDInfo));
5017
5018 if(NULL == scanRequest.SSIDs.SSIDList)
5019 {
5020 hddLog(VOS_TRACE_LEVEL_ERROR,
5021 "memory alloc failed SSIDInfo buffer");
5022 return -ENOMEM;
5023 }
5024
5025 /* copy all the ssid's and their length */
5026 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5027 {
5028 /* get the ssid length */
5029 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5030 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5031 SsidInfo->SSID.length);
5032 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
5033 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
5034 j, SsidInfo->SSID.ssId);
5035 }
5036 /* set the scan type to active */
5037 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5038 }
5039 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5040 {
5041 /* set the scan type to active */
5042 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5043 }
5044 else
5045 {
5046 /*Set the scan type to default type, in this case it is ACTIVE*/
5047 scanRequest.scanType = pScanInfo->scan_mode;
5048 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305049 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5051 }
5052 else
5053 {
5054 /* set the scan type to active */
5055 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5056 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5057
5058 /* set min and max channel time to zero */
5059 scanRequest.minChnTime = 0;
5060 scanRequest.maxChnTime = 0;
5061 }
5062
5063 /* set BSSType to default type */
5064 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5065
5066 /*TODO: scan the requested channels only*/
5067
5068 /*Right now scanning all the channels */
5069 if( request )
5070 {
5071 if( request->n_channels )
5072 {
5073 channelList = vos_mem_malloc( request->n_channels );
5074 if( NULL == channelList )
5075 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305076 hddLog(VOS_TRACE_LEVEL_ERROR,
5077 "channelList memory alloc failed channelList");
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 status = -ENOMEM;
5079 goto free_mem;
5080 }
5081
5082 for( i = 0 ; i < request->n_channels ; i++ )
5083 channelList[i] = request->channels[i]->hw_value;
5084 }
5085
5086 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5087 scanRequest.ChannelInfo.ChannelList = channelList;
5088
5089 /* set requestType to full scan */
5090 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305091
5092 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005093 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005095 */
5096
5097 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305098 * and in that case driver shoudnt flush scan results. If
5099 * driver flushes the scan results here and unfortunately if
5100 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005101 * fails which is not desired
5102 */
5103
5104 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5105 {
5106 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5107 pAdapter->sessionId );
5108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005109
5110 if( request->ie_len )
5111 {
5112 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305113 /*TODO: Array needs to be converted to dynamic allocation,
5114 * as multiple ie.s can be sent in cfg80211_scan_request structure
5115 * CR 597966
5116 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005117 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5118 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5119 pScanInfo->scanAddIE.length = request->ie_len;
5120
Agarwal Ashish4f616132013-12-30 23:32:50 +05305121 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005122 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305123 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305125 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5126 {
5127 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5128 memcpy( pwextBuf->roamProfile.addIEScan,
5129 request->ie, request->ie_len);
5130 }
5131 else
5132 {
5133 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5134 "%d", request->ie_len);
5135 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005136
Agarwal Ashish4f616132013-12-30 23:32:50 +05305137 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5139 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5140
Jeff Johnson295189b2012-06-20 16:38:30 -07005141 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5142 request->ie_len);
5143 if (pP2pIe != NULL)
5144 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005145#ifdef WLAN_FEATURE_P2P_DEBUG
5146 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5147 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5148 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5149 {
5150 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5151 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5152 "Go nego completed to Connection is started");
5153 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5154 "for 8way Handshake");
5155 }
5156 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5157 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5158 {
5159 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5160 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5161 "Disconnected state to Connection is started");
5162 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5163 "for 4way Handshake");
5164 }
5165#endif
5166
Jeff Johnsone7245742012-09-05 17:12:55 -07005167 /* no_cck will be set during p2p find to disable 11b rates */
5168 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005169 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005170 hddLog(VOS_TRACE_LEVEL_INFO,
5171 "%s: This is a P2P Search", __func__);
5172 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005173
Jeff Johnsone7245742012-09-05 17:12:55 -07005174 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5175 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005176 /* set requestType to P2P Discovery */
5177 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005178 }
5179
5180 /*
5181 Skip Dfs Channel in case of P2P Search
5182 if it is set in ini file
5183 */
5184 if(cfg_param->skipDfsChnlInP2pSearch)
5185 {
5186 scanRequest.skipDfsChnlInP2pSearch = 1;
5187 }
5188 else
5189 {
5190 scanRequest.skipDfsChnlInP2pSearch = 0;
5191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005192
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 }
5194 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 }
5196 }
5197
5198 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5199
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005200 /* acquire the wakelock to avoid the apps suspend during the scan. To
5201 * address the following issues.
5202 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5203 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5204 * for long time, this result in apps running at full power for long time.
5205 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5206 * be stuck in full power because of resume BMPS
5207 */
5208 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005209
5210 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 pAdapter->sessionId, &scanRequest, &scanId,
5212 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005213
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 if (eHAL_STATUS_SUCCESS != status)
5215 {
5216 hddLog(VOS_TRACE_LEVEL_ERROR,
5217 "%s: sme_ScanRequest returned error %d", __func__, status);
5218 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005219 if(eHAL_STATUS_RESOURCES == status)
5220 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07005221 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 -07005222 status = -EBUSY;
5223 } else {
5224 status = -EIO;
5225 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005226 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005227 goto free_mem;
5228 }
5229
5230 pScanInfo->mScanPending = TRUE;
5231 pAdapter->request = request;
5232 pScanInfo->scanId = scanId;
5233
5234 complete(&pScanInfo->scan_req_completion_event);
5235
5236free_mem:
5237 if( scanRequest.SSIDs.SSIDList )
5238 {
5239 vos_mem_free(scanRequest.SSIDs.SSIDList);
5240 }
5241
5242 if( channelList )
5243 vos_mem_free( channelList );
5244
5245 EXIT();
5246
5247 return status;
5248}
5249
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005250
5251void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5252{
5253 v_U8_t iniDot11Mode =
5254 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5255 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5256
5257 switch ( iniDot11Mode )
5258 {
5259 case eHDD_DOT11_MODE_AUTO:
5260 case eHDD_DOT11_MODE_11ac:
5261 case eHDD_DOT11_MODE_11ac_ONLY:
5262#ifdef WLAN_FEATURE_11AC
5263 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5264#else
5265 hddDot11Mode = eHDD_DOT11_MODE_11n;
5266#endif
5267 break;
5268 case eHDD_DOT11_MODE_11n:
5269 case eHDD_DOT11_MODE_11n_ONLY:
5270 hddDot11Mode = eHDD_DOT11_MODE_11n;
5271 break;
5272 default:
5273 hddDot11Mode = iniDot11Mode;
5274 break;
5275 }
5276 /* This call decides required channel bonding mode */
5277 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5278 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5279 operationChannel);
5280}
5281
Jeff Johnson295189b2012-06-20 16:38:30 -07005282/*
5283 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305284 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005285 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305286int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005287 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005288{
5289 int status = 0;
5290 hdd_wext_state_t *pWextState;
5291 v_U32_t roamId;
5292 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005293 eCsrAuthType RSNAuthType;
5294
5295 ENTER();
5296
5297 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305298
Jeff Johnson295189b2012-06-20 16:38:30 -07005299 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5300 {
5301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5302 return -EINVAL;
5303 }
5304
5305 pRoamProfile = &pWextState->roamProfile;
5306
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005309 hdd_station_ctx_t *pHddStaCtx;
5310 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005311
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305312 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005313 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5314 {
5315 /*QoS not enabled in cfg file*/
5316 pRoamProfile->uapsd_mask = 0;
5317 }
5318 else
5319 {
5320 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305321 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005322 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5323 }
5324
5325 pRoamProfile->SSIDs.numOfSSIDs = 1;
5326 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5327 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305328 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005329 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5330 ssid, ssid_len);
5331
5332 if (bssid)
5333 {
5334 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5335 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5336 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305337 /* Save BSSID in seperate variable as well, as RoamProfile
5338 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 case of join failure we should send valid BSSID to supplicant
5340 */
5341 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5342 WNI_CFG_BSSID_LEN);
5343 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005344 else
5345 {
5346 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005348
5349 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5350 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305351 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 /*set gen ie*/
5353 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5354 /*set auth*/
5355 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005357#ifdef FEATURE_WLAN_WAPI
5358 if (pAdapter->wapi_info.nWapiMode)
5359 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005360 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 switch (pAdapter->wapi_info.wapiAuthMode)
5362 {
5363 case WAPI_AUTH_MODE_PSK:
5364 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005365 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 pAdapter->wapi_info.wapiAuthMode);
5367 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5368 break;
5369 }
5370 case WAPI_AUTH_MODE_CERT:
5371 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005372 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 pAdapter->wapi_info.wapiAuthMode);
5374 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5375 break;
5376 }
5377 } // End of switch
5378 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5379 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5380 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005381 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 pRoamProfile->AuthType.numEntries = 1;
5383 pRoamProfile->EncryptionType.numEntries = 1;
5384 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5385 pRoamProfile->mcEncryptionType.numEntries = 1;
5386 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5387 }
5388 }
5389#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305390#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305391 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305392 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5393 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5394 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305395 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5396 sizeof (tSirGtkOffloadParams));
5397 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305398 }
5399#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 pRoamProfile->csrPersona = pAdapter->device_mode;
5401
Jeff Johnson32d95a32012-09-10 13:15:23 -07005402 if( operatingChannel )
5403 {
5404 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5405 pRoamProfile->ChannelInfo.numOfChannels = 1;
5406 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005407 else
5408 {
5409 pRoamProfile->ChannelInfo.ChannelList = NULL;
5410 pRoamProfile->ChannelInfo.numOfChannels = 0;
5411 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005412 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5413 {
5414 hdd_select_cbmode(pAdapter,operatingChannel);
5415 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005416 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5417 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005419 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005420 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5421 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305422 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5423 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005424 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5425 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305426
5427 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 pAdapter->sessionId, pRoamProfile, &roamId);
5429
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305430 if ((eHAL_STATUS_SUCCESS != status) &&
5431 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5432 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305433
5434 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5436 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5437 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305438 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005439 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305440 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005441
5442 pRoamProfile->ChannelInfo.ChannelList = NULL;
5443 pRoamProfile->ChannelInfo.numOfChannels = 0;
5444
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 }
5446 else
5447 {
5448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5449 return -EINVAL;
5450 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005451 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 return status;
5453}
5454
5455/*
5456 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5457 * This function is used to set the authentication type (OPEN/SHARED).
5458 *
5459 */
5460static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5461 enum nl80211_auth_type auth_type)
5462{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305463 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5465
5466 ENTER();
5467
5468 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305469 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305472 hddLog(VOS_TRACE_LEVEL_INFO,
5473 "%s: set authentication type to AUTOSWITCH", __func__);
5474 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5475 break;
5476
5477 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005478#ifdef WLAN_FEATURE_VOWIFI_11R
5479 case NL80211_AUTHTYPE_FT:
5480#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 "%s: set authentication type to OPEN", __func__);
5483 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5484 break;
5485
5486 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 "%s: set authentication type to SHARED", __func__);
5489 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5490 break;
5491#ifdef FEATURE_WLAN_CCX
5492 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305493 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 "%s: set authentication type to CCKM WPA", __func__);
5495 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5496 break;
5497#endif
5498
5499
5500 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305501 hddLog(VOS_TRACE_LEVEL_ERROR,
5502 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 auth_type);
5504 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5505 return -EINVAL;
5506 }
5507
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305508 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 pHddStaCtx->conn_info.authType;
5510 return 0;
5511}
5512
5513/*
5514 * FUNCTION: wlan_hdd_set_akm_suite
5515 * This function is used to set the key mgmt type(PSK/8021x).
5516 *
5517 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305518static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 u32 key_mgmt
5520 )
5521{
5522 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5523 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305524
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 /*set key mgmt type*/
5526 switch(key_mgmt)
5527 {
5528 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305529#ifdef WLAN_FEATURE_VOWIFI_11R
5530 case WLAN_AKM_SUITE_FT_PSK:
5531#endif
5532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 __func__);
5534 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5535 break;
5536
5537 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305538#ifdef WLAN_FEATURE_VOWIFI_11R
5539 case WLAN_AKM_SUITE_FT_8021X:
5540#endif
5541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 __func__);
5543 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5544 break;
5545#ifdef FEATURE_WLAN_CCX
5546#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5547#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5548 case WLAN_AKM_SUITE_CCKM:
5549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5550 __func__);
5551 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5552 break;
5553#endif
5554
5555 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 __func__, key_mgmt);
5558 return -EINVAL;
5559
5560 }
5561 return 0;
5562}
5563
5564/*
5565 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305566 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 * (NONE/WEP40/WEP104/TKIP/CCMP).
5568 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305569static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5570 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 bool ucast
5572 )
5573{
5574 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305575 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5577
5578 ENTER();
5579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 __func__, cipher);
5584 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5585 }
5586 else
5587 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305588
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305590 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 {
5592 case IW_AUTH_CIPHER_NONE:
5593 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5594 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305595
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305597 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305599
Jeff Johnson295189b2012-06-20 16:38:30 -07005600 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305601 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305603
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 case WLAN_CIPHER_SUITE_TKIP:
5605 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5606 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305607
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 case WLAN_CIPHER_SUITE_CCMP:
5609 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5610 break;
5611#ifdef FEATURE_WLAN_WAPI
5612 case WLAN_CIPHER_SUITE_SMS4:
5613 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5614 break;
5615#endif
5616
5617#ifdef FEATURE_WLAN_CCX
5618 case WLAN_CIPHER_SUITE_KRK:
5619 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5620 break;
5621#endif
5622 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 __func__, cipher);
5625 return -EOPNOTSUPP;
5626 }
5627 }
5628
5629 if (ucast)
5630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 __func__, encryptionType);
5633 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5634 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305635 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 encryptionType;
5637 }
5638 else
5639 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305640 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 __func__, encryptionType);
5642 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5643 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5644 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5645 }
5646
5647 return 0;
5648}
5649
5650
5651/*
5652 * FUNCTION: wlan_hdd_cfg80211_set_ie
5653 * This function is used to parse WPA/RSN IE's.
5654 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5656 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 size_t ie_len
5658 )
5659{
5660 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5661 u8 *genie = ie;
5662 v_U16_t remLen = ie_len;
5663#ifdef FEATURE_WLAN_WAPI
5664 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5665 u16 *tmp;
5666 v_U16_t akmsuiteCount;
5667 int *akmlist;
5668#endif
5669 ENTER();
5670
5671 /* clear previous assocAddIE */
5672 pWextState->assocAddIE.length = 0;
5673 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5674
5675 while (remLen >= 2)
5676 {
5677 v_U16_t eLen = 0;
5678 v_U8_t elementId;
5679 elementId = *genie++;
5680 eLen = *genie++;
5681 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305682
Arif Hussain6d2a3322013-11-17 19:50:10 -08005683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005684 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685
5686 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305688 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005689 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 -07005690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305691 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 "%s: Invalid WPA IE", __func__);
5693 return -EINVAL;
5694 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305695 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 {
5697 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305698 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5702 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005703 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5704 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 VOS_ASSERT(0);
5706 return -ENOMEM;
5707 }
5708 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5709 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5710 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305711
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5713 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5714 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5715 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305716 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5717 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5719 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5720 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5721 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5722 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5723 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305724 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305725 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005726 {
5727 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305728 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5732 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005733 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5734 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 VOS_ASSERT(0);
5736 return -ENOMEM;
5737 }
5738 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5739 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5740 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5743 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005745#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305746 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5747 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 /*Consider WFD IE, only for P2P Client */
5749 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5750 {
5751 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305752 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5756 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005757 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5758 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 VOS_ASSERT(0);
5760 return -ENOMEM;
5761 }
5762 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5763 // WPS IE + P2P IE + WFD IE
5764 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5765 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305766
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5768 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5769 }
5770#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005771 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005773 HS20_OUI_TYPE_SIZE)) )
5774 {
5775 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305776 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005777 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005778
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005779 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5780 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005781 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5782 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005783 VOS_ASSERT(0);
5784 return -ENOMEM;
5785 }
5786 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5787 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005788
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005789 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5790 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5791 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005792
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005793 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5794
5795 /* populating as ADDIE in beacon frames */
5796 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5797 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5798 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5799 {
5800 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5801 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5802 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5803 {
5804 hddLog(LOGE,
5805 "Coldn't pass "
5806 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5807 }
5808 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5809 else
5810 hddLog(LOGE,
5811 "Could not pass on "
5812 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5813
5814 /* IBSS mode doesn't contain params->proberesp_ies still
5815 beaconIE's need to be populated in probe response frames */
5816 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5817 {
5818 u16 rem_probe_resp_ie_len = eLen + 2;
5819 u8 probe_rsp_ie_len[3] = {0};
5820 u8 counter = 0;
5821
5822 /* Check Probe Resp Length if it is greater then 255 then
5823 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5824 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5825 not able Store More then 255 bytes into One Variable */
5826
5827 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5828 {
5829 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5830 {
5831 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5832 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5833 }
5834 else
5835 {
5836 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5837 rem_probe_resp_ie_len = 0;
5838 }
5839 }
5840
5841 rem_probe_resp_ie_len = 0;
5842
5843 if (probe_rsp_ie_len[0] > 0)
5844 {
5845 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5846 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5847 (tANI_U8*)(genie - 2),
5848 probe_rsp_ie_len[0], NULL,
5849 eANI_BOOLEAN_FALSE)
5850 == eHAL_STATUS_FAILURE)
5851 {
5852 hddLog(LOGE,
5853 "Could not pass"
5854 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
5855 }
5856 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5857 }
5858
5859 if (probe_rsp_ie_len[1] > 0)
5860 {
5861 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5862 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5863 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
5864 probe_rsp_ie_len[1], NULL,
5865 eANI_BOOLEAN_FALSE)
5866 == eHAL_STATUS_FAILURE)
5867 {
5868 hddLog(LOGE,
5869 "Could not pass"
5870 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
5871 }
5872 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5873 }
5874
5875 if (probe_rsp_ie_len[2] > 0)
5876 {
5877 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5878 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5879 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
5880 probe_rsp_ie_len[2], NULL,
5881 eANI_BOOLEAN_FALSE)
5882 == eHAL_STATUS_FAILURE)
5883 {
5884 hddLog(LOGE,
5885 "Could not pass"
5886 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
5887 }
5888 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5889 }
5890
5891 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5892 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5893 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5894 {
5895 hddLog(LOGE,
5896 "Could not pass"
5897 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
5898 }
5899 }
5900 else
5901 {
5902 // Reset WNI_CFG_PROBE_RSP Flags
5903 wlan_hdd_reset_prob_rspies(pAdapter);
5904
5905 hddLog(VOS_TRACE_LEVEL_INFO,
5906 "%s: No Probe Response IE received in set beacon",
5907 __func__);
5908 }
5909 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 break;
5911 case DOT11F_EID_RSN:
5912 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5913 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5914 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5915 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5916 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5917 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005918 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5919 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005921 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305922 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005923 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005925 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5926 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005927 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5928 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005929 VOS_ASSERT(0);
5930 return -ENOMEM;
5931 }
5932 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5933 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305934
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005935 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5936 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5937 break;
5938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005939#ifdef FEATURE_WLAN_WAPI
5940 case WLAN_EID_WAPI:
5941 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005942 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 pAdapter->wapi_info.nWapiMode);
5944 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 akmsuiteCount = WPA_GET_LE16(tmp);
5947 tmp = tmp + 1;
5948 akmlist = (int *)(tmp);
5949 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5950 {
5951 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5952 }
5953 else
5954 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005955 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 VOS_ASSERT(0);
5957 return -EINVAL;
5958 }
5959
5960 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5961 {
5962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005963 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005964 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305965 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305967 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005969 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5971 }
5972 break;
5973#endif
5974 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305975 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005977 /* when Unknown IE is received we should break and continue
5978 * to the next IE in the buffer instead we were returning
5979 * so changing this to break */
5980 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 }
5982 genie += eLen;
5983 remLen -= eLen;
5984 }
5985 EXIT();
5986 return 0;
5987}
5988
5989/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305990 * FUNCTION: hdd_isWPAIEPresent
5991 * Parse the received IE to find the WPA IE
5992 *
5993 */
5994static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5995{
5996 v_U8_t eLen = 0;
5997 v_U16_t remLen = ie_len;
5998 v_U8_t elementId = 0;
5999
6000 while (remLen >= 2)
6001 {
6002 elementId = *ie++;
6003 eLen = *ie++;
6004 remLen -= 2;
6005 if (eLen > remLen)
6006 {
6007 hddLog(VOS_TRACE_LEVEL_ERROR,
6008 "%s: IE length is wrong %d", __func__, eLen);
6009 return FALSE;
6010 }
6011 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6012 {
6013 /* OUI - 0x00 0X50 0XF2
6014 WPA Information Element - 0x01
6015 WPA version - 0x01*/
6016 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6017 return TRUE;
6018 }
6019 ie += eLen;
6020 remLen -= eLen;
6021 }
6022 return FALSE;
6023}
6024
6025/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 * parameters during connect operation.
6029 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 struct cfg80211_connect_params *req
6032 )
6033{
6034 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 ENTER();
6037
6038 /*set wpa version*/
6039 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6040
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306043 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 {
6045 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6046 }
6047 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6048 {
6049 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6050 }
6051 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306052
6053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 pWextState->wpaVersion);
6055
6056 /*set authentication type*/
6057 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6058
6059 if (0 > status)
6060 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306061 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 "%s: failed to set authentication type ", __func__);
6063 return status;
6064 }
6065
6066 /*set key mgmt type*/
6067 if (req->crypto.n_akm_suites)
6068 {
6069 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6070 if (0 > status)
6071 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 __func__);
6074 return status;
6075 }
6076 }
6077
6078 /*set pairwise cipher type*/
6079 if (req->crypto.n_ciphers_pairwise)
6080 {
6081 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6082 req->crypto.ciphers_pairwise[0], true);
6083 if (0 > status)
6084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306085 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 "%s: failed to set unicast cipher type", __func__);
6087 return status;
6088 }
6089 }
6090 else
6091 {
6092 /*Reset previous cipher suite to none*/
6093 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6094 if (0 > status)
6095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 "%s: failed to set unicast cipher type", __func__);
6098 return status;
6099 }
6100 }
6101
6102 /*set group cipher type*/
6103 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6104 false);
6105
6106 if (0 > status)
6107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 __func__);
6110 return status;
6111 }
6112
Chet Lanctot186b5732013-03-18 10:26:30 -07006113#ifdef WLAN_FEATURE_11W
6114 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6115#endif
6116
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6118 if (req->ie_len)
6119 {
6120 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6121 if ( 0 > status)
6122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 __func__);
6125 return status;
6126 }
6127 }
6128
6129 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306130 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 {
6132 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6133 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6134 )
6135 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306136 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 __func__);
6141 return -EOPNOTSUPP;
6142 }
6143 else
6144 {
6145 u8 key_len = req->key_len;
6146 u8 key_idx = req->key_idx;
6147
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306148 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 && (CSR_MAX_NUM_KEY > key_idx)
6150 )
6151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306152 hddLog(VOS_TRACE_LEVEL_INFO,
6153 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 __func__, key_idx, key_len);
6155 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306156 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006157 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306158 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 (u8)key_len;
6160 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6161 }
6162 }
6163 }
6164 }
6165
6166 return status;
6167}
6168
6169/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306170 * FUNCTION: wlan_hdd_try_disconnect
6171 * This function is used to disconnect from previous
6172 * connection
6173 */
6174static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6175{
6176 long ret = 0;
6177 hdd_station_ctx_t *pHddStaCtx;
6178 eMib_dot11DesiredBssType connectedBssType;
6179
6180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6181
6182 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6183
6184 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6185 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6186 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6187 {
6188 /* Issue disconnect to CSR */
6189 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6190 if( eHAL_STATUS_SUCCESS ==
6191 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6192 pAdapter->sessionId,
6193 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6194 {
6195 ret = wait_for_completion_interruptible_timeout(
6196 &pAdapter->disconnect_comp_var,
6197 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6198 if (0 >= ret)
6199 {
6200 hddLog(LOGE, FL("Failed to receive disconnect event"));
6201 return -EALREADY;
6202 }
6203 }
6204 }
6205 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6206 {
6207 ret = wait_for_completion_interruptible_timeout(
6208 &pAdapter->disconnect_comp_var,
6209 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6210 if (0 >= ret)
6211 {
6212 hddLog(LOGE, FL("Failed to receive disconnect event"));
6213 return -EALREADY;
6214 }
6215 }
6216
6217 return 0;
6218}
6219
6220/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306222 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 * parameters during connect operation.
6224 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306225static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 struct net_device *ndev,
6227 struct cfg80211_connect_params *req
6228 )
6229{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306230 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
6233 hdd_context_t *pHddCtx = NULL;
6234
6235 ENTER();
6236
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006238 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006239
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6241 status = wlan_hdd_validate_context(pHddCtx);
6242
6243 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6246 "%s: HDD context is not valid", __func__);
6247 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 }
6249
6250#ifdef WLAN_BTAMP_FEATURE
6251 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306252 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306254 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006256 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 }
6258#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306259
6260 //If Device Mode is Station Concurrent Sessions Exit BMps
6261 //P2P Mode will be taken care in Open/close adapter
6262 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6263 (vos_concurrent_sessions_running()))
6264 {
6265 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6266 }
6267
6268 /*Try disconnecting if already in connected state*/
6269 status = wlan_hdd_try_disconnect(pAdapter);
6270 if ( 0 > status)
6271 {
6272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6273 " connection"));
6274 return -EALREADY;
6275 }
6276
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306278 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006279
6280 if ( 0 > status)
6281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 __func__);
6284 return status;
6285 }
6286
Mohit Khanna765234a2012-09-11 15:08:35 -07006287 if ( req->channel )
6288 {
6289 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6290 req->ssid_len, req->bssid,
6291 req->channel->hw_value);
6292 }
6293 else
6294 {
6295 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306296 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006298
6299 if (0 > status)
6300 {
6301 //ReEnable BMPS if disabled
6302 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6303 (NULL != pHddCtx))
6304 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306305 if (pHddCtx->hdd_wlan_suspended)
6306 {
6307 hdd_set_pwrparams(pHddCtx);
6308 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 //ReEnable Bmps and Imps back
6310 hdd_enable_bmps_imps(pHddCtx);
6311 }
6312
6313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6314 return status;
6315 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306316 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 EXIT();
6318 return status;
6319}
6320
6321
6322/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306323 * FUNCTION: wlan_hdd_disconnect
6324 * This function is used to issue a disconnect request to SME
6325 */
6326int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6327{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306328 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306329 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306330 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306331 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306332
6333 status = wlan_hdd_validate_context(pHddCtx);
6334
6335 if (0 != status)
6336 {
6337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6338 "%s: HDD context is not valid", __func__);
6339 return status;
6340 }
6341
6342 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306343 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306344 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306345
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306346 /*issue disconnect*/
6347 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6348 pAdapter->sessionId, reason);
6349
6350 if ( 0 != status )
6351 {
6352 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006353 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306354 __func__, (int)status );
6355 return -EINVAL;
6356 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306358 &pAdapter->disconnect_comp_var,
6359 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306360 if (ret <= 0)
6361 {
6362 hddLog(VOS_TRACE_LEVEL_ERROR,
6363 FL("wait on disconnect_comp_var failed %ld"), ret);
6364 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306365 /*stop tx queues*/
6366 netif_tx_disable(pAdapter->dev);
6367 netif_carrier_off(pAdapter->dev);
6368 return status;
6369}
6370
6371
6372/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 * FUNCTION: wlan_hdd_cfg80211_disconnect
6374 * This function is used to issue a disconnect request to SME
6375 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306376static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 struct net_device *dev,
6378 u16 reason
6379 )
6380{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6382 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306384 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006386 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306387#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006388 tANI_U8 staIdx;
6389#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306390
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306392
Arif Hussain6d2a3322013-11-17 19:50:10 -08006393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 __func__,pAdapter->device_mode);
6395
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6397 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006398
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306399 status = wlan_hdd_validate_context(pHddCtx);
6400
6401 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6404 "%s: HDD context is not valid", __func__);
6405 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306407
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 if (NULL != pRoamProfile)
6409 {
6410 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306411 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6412 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306416 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 switch(reason)
6418 {
6419 case WLAN_REASON_MIC_FAILURE:
6420 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6421 break;
6422
6423 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6424 case WLAN_REASON_DISASSOC_AP_BUSY:
6425 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6426 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6427 break;
6428
6429 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6430 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6431 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6432 break;
6433
6434 case WLAN_REASON_DEAUTH_LEAVING:
6435 default:
6436 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6437 break;
6438 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306439 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6440 pScanInfo = &pHddCtx->scan_info;
6441 if (pScanInfo->mScanPending)
6442 {
6443 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
6444 "Aborting Scan");
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05306445 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006447
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006448#ifdef FEATURE_WLAN_TDLS
6449 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006450 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006451 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006452 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6453 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006454 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006455 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006456 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006457 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006458 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006459 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006460 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006461 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006462 pAdapter->sessionId,
6463 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006464 }
6465 }
6466#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306467 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6468 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 {
6470 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006471 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 __func__, (int)status );
6473 return -EINVAL;
6474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306476 else
6477 {
6478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6479 "called while in %d state", __func__,
6480 pHddStaCtx->conn_info.connState);
6481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 }
6483 else
6484 {
6485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6486 }
6487
6488 return status;
6489}
6490
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306491
Jeff Johnson295189b2012-06-20 16:38:30 -07006492/*
6493 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306494 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 * settings in IBSS mode.
6496 */
6497static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306498 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 struct cfg80211_ibss_params *params
6500 )
6501{
6502 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306503 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6505 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306506
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 ENTER();
6508
6509 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006510 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006511
6512 if (params->ie_len && ( NULL != params->ie) )
6513 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006514 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6515 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 {
6517 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6518 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6519 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006520 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006521 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006522 tDot11fIEWPA dot11WPAIE;
6523 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006524 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006525
Wilson Yang00256342013-10-10 23:13:38 -07006526 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006527 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6528 params->ie_len, DOT11F_EID_WPA);
6529 if ( NULL != ie )
6530 {
6531 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6532 // Unpack the WPA IE
6533 //Skip past the EID byte and length byte - and four byte WiFi OUI
6534 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6535 &ie[2+4],
6536 ie[1] - 4,
6537 &dot11WPAIE);
6538 /*Extract the multicast cipher, the encType for unicast
6539 cipher for wpa-none is none*/
6540 encryptionType =
6541 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006544
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6546
6547 if (0 > status)
6548 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 __func__);
6551 return status;
6552 }
6553 }
6554
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306555 pWextState->roamProfile.AuthType.authType[0] =
6556 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6558
6559 if (params->privacy)
6560 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306561 /* Security enabled IBSS, At this time there is no information available
6562 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306564 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006565 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306566 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 *enable privacy bit in beacons */
6568
6569 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6570 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006571 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6572 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6574 pWextState->roamProfile.EncryptionType.numEntries = 1;
6575 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 return status;
6577}
6578
6579/*
6580 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306581 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006582 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306583static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 struct net_device *dev,
6585 struct cfg80211_ibss_params *params
6586 )
6587{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6590 tCsrRoamProfile *pRoamProfile;
6591 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006592 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306594 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006595
6596 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306597
6598 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006599 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306601 status = wlan_hdd_validate_context(pHddCtx);
6602
6603 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6606 "%s: HDD context is not valid", __func__);
6607 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 }
6609
6610 if (NULL == pWextState)
6611 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006612 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 __func__);
6614 return -EIO;
6615 }
6616
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306617 /*Try disconnecting if already in connected state*/
6618 status = wlan_hdd_try_disconnect(pAdapter);
6619 if ( 0 > status)
6620 {
6621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6622 " IBSS connection"));
6623 return -EALREADY;
6624 }
6625
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 pRoamProfile = &pWextState->roamProfile;
6627
6628 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6629 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306630 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006631 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 return -EINVAL;
6633 }
6634
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006635 /* BSSID is provided by upper layers hence no need to AUTO generate */
6636 if (NULL != params->bssid) {
6637 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6638 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6639 hddLog (VOS_TRACE_LEVEL_ERROR,
6640 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6641 return -EIO;
6642 }
6643 }
krunal sonie9002db2013-11-25 14:24:17 -08006644 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6645 {
6646 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6647 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6648 {
6649 hddLog (VOS_TRACE_LEVEL_ERROR,
6650 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6651 return -EIO;
6652 }
6653 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6654 if (!params->bssid)
6655 {
6656 hddLog (VOS_TRACE_LEVEL_ERROR,
6657 "%s:Failed memory allocation", __func__);
6658 return -EIO;
6659 }
6660 vos_mem_copy((v_U8_t *)params->bssid,
6661 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6662 VOS_MAC_ADDR_SIZE);
6663 alloc_bssid = VOS_TRUE;
6664 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006665
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006667 if (NULL !=
6668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6669 params->chandef.chan)
6670#else
6671 params->channel)
6672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 {
6674 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006675 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6676 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6677 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6678 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006679
6680 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306681 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006682 ieee80211_frequency_to_channel(
6683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6684 params->chandef.chan->center_freq);
6685#else
6686 params->channel->center_freq);
6687#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006688
6689 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6690 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6693 __func__);
6694 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006696
6697 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006699 if (channelNum == validChan[indx])
6700 {
6701 break;
6702 }
6703 }
6704 if (indx >= numChans)
6705 {
6706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 __func__, channelNum);
6708 return -EINVAL;
6709 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006710 /* Set the Operational Channel */
6711 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6712 channelNum);
6713 pRoamProfile->ChannelInfo.numOfChannels = 1;
6714 pHddStaCtx->conn_info.operationChannel = channelNum;
6715 pRoamProfile->ChannelInfo.ChannelList =
6716 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006717 }
6718
6719 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306720 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 if (status < 0)
6722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 __func__);
6725 return status;
6726 }
6727
6728 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306729 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006730 params->ssid_len, params->bssid,
6731 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006732
6733 if (0 > status)
6734 {
6735 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6736 return status;
6737 }
6738
krunal sonie9002db2013-11-25 14:24:17 -08006739 if (NULL != params->bssid &&
6740 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6741 alloc_bssid == VOS_TRUE)
6742 {
6743 vos_mem_free(params->bssid);
6744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 return 0;
6746}
6747
6748/*
6749 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306750 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306752static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 struct net_device *dev
6754 )
6755{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306756 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6758 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306759 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6760 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006761
6762 ENTER();
6763
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306764 status = wlan_hdd_validate_context(pHddCtx);
6765
6766 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006767 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6769 "%s: HDD context is not valid", __func__);
6770 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006771 }
6772
Arif Hussain6d2a3322013-11-17 19:50:10 -08006773 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 if (NULL == pWextState)
6775 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006776 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 __func__);
6778 return -EIO;
6779 }
6780
6781 pRoamProfile = &pWextState->roamProfile;
6782
6783 /* Issue disconnect only if interface type is set to IBSS */
6784 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 __func__);
6788 return -EINVAL;
6789 }
6790
6791 /* Issue Disconnect request */
6792 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6793 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6794 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6795
6796 return 0;
6797}
6798
6799/*
6800 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6801 * This function is used to set the phy parameters
6802 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6803 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306804static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 u32 changed)
6806{
6807 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6808 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306809 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006810
6811 ENTER();
6812
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306813 status = wlan_hdd_validate_context(pHddCtx);
6814
6815 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006816 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6818 "%s: HDD context is not valid", __func__);
6819 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006820 }
6821
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6823 {
6824 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6825 WNI_CFG_RTS_THRESHOLD_STAMAX :
6826 wiphy->rts_threshold;
6827
6828 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306829 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306831 hddLog(VOS_TRACE_LEVEL_ERROR,
6832 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 __func__, rts_threshold);
6834 return -EINVAL;
6835 }
6836
6837 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6838 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306839 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306841 hddLog(VOS_TRACE_LEVEL_ERROR,
6842 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 __func__, rts_threshold);
6844 return -EIO;
6845 }
6846
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306847 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 rts_threshold);
6849 }
6850
6851 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6852 {
6853 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6854 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6855 wiphy->frag_threshold;
6856
6857 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306858 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306860 hddLog(VOS_TRACE_LEVEL_ERROR,
6861 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 frag_threshold);
6863 return -EINVAL;
6864 }
6865
6866 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6867 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306870 hddLog(VOS_TRACE_LEVEL_ERROR,
6871 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 __func__, frag_threshold);
6873 return -EIO;
6874 }
6875
6876 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6877 frag_threshold);
6878 }
6879
6880 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6881 || (changed & WIPHY_PARAM_RETRY_LONG))
6882 {
6883 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6884 wiphy->retry_short :
6885 wiphy->retry_long;
6886
6887 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6888 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 __func__, retry_value);
6892 return -EINVAL;
6893 }
6894
6895 if (changed & WIPHY_PARAM_RETRY_SHORT)
6896 {
6897 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6898 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 hddLog(VOS_TRACE_LEVEL_ERROR,
6902 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 __func__, retry_value);
6904 return -EIO;
6905 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 __func__, retry_value);
6908 }
6909 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6910 {
6911 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6912 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306913 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 hddLog(VOS_TRACE_LEVEL_ERROR,
6916 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 __func__, retry_value);
6918 return -EIO;
6919 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 __func__, retry_value);
6922 }
6923 }
6924
6925 return 0;
6926}
6927
6928/*
6929 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6930 * This function is used to set the txpower
6931 */
6932static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07006933#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
6934 struct wireless_dev *wdev,
6935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006936#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306937 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306939 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006940#endif
6941 int dbm)
6942{
6943 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306944 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006945 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6946 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306947 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006948
6949 ENTER();
6950
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306951 status = wlan_hdd_validate_context(pHddCtx);
6952
6953 if (0 != status)
6954 {
6955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6956 "%s: HDD context is not valid", __func__);
6957 return status;
6958 }
6959
6960 hHal = pHddCtx->hHal;
6961
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306962 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6963 dbm, ccmCfgSetCallback,
6964 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306966 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6968 return -EIO;
6969 }
6970
6971 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6972 dbm);
6973
6974 switch(type)
6975 {
6976 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6977 /* Fall through */
6978 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6979 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6982 __func__);
6983 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 }
6985 break;
6986 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 __func__);
6989 return -EOPNOTSUPP;
6990 break;
6991 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6993 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 return -EIO;
6995 }
6996
6997 return 0;
6998}
6999
7000/*
7001 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7002 * This function is used to read the txpower
7003 */
Yue Maf49ba872013-08-19 12:04:25 -07007004static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7005#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7006 struct wireless_dev *wdev,
7007#endif
7008 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007009{
7010
7011 hdd_adapter_t *pAdapter;
7012 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307013 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007014
Jeff Johnsone7245742012-09-05 17:12:55 -07007015 ENTER();
7016
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307017 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007018
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307019 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7022 "%s: HDD context is not valid", __func__);
7023 *dbm = 0;
7024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007025 }
7026
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7028 if (NULL == pAdapter)
7029 {
7030 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7031 return -ENOENT;
7032 }
7033
7034 wlan_hdd_get_classAstats(pAdapter);
7035 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7036
Jeff Johnsone7245742012-09-05 17:12:55 -07007037 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 return 0;
7039}
7040
7041static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7042 u8* mac, struct station_info *sinfo)
7043{
7044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7045 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7046 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7047 tANI_U8 rate_flags;
7048
7049 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7050 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007051
7052 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7053 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7054 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7055 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7056 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7057 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7058 tANI_U16 maxRate = 0;
7059 tANI_U16 myRate;
7060 tANI_U16 currentRate = 0;
7061 tANI_U8 maxSpeedMCS = 0;
7062 tANI_U8 maxMCSIdx = 0;
7063 tANI_U8 rateFlag = 1;
7064 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007065 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307066 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007067
Leo Chang6f8870f2013-03-26 18:11:36 -07007068#ifdef WLAN_FEATURE_11AC
7069 tANI_U32 vht_mcs_map;
7070 eDataRate11ACMaxMcs vhtMaxMcs;
7071#endif /* WLAN_FEATURE_11AC */
7072
Jeff Johnsone7245742012-09-05 17:12:55 -07007073 ENTER();
7074
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7076 (0 == ssidlen))
7077 {
7078 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7079 " Invalid ssidlen, %d", __func__, ssidlen);
7080 /*To keep GUI happy*/
7081 return 0;
7082 }
7083
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307084 status = wlan_hdd_validate_context(pHddCtx);
7085
7086 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007087 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7089 "%s: HDD context is not valid", __func__);
7090 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007091 }
7092
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007093 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7095
Kiet Lam3b17fc82013-09-27 05:24:08 +05307096 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7097 sinfo->filled |= STATION_INFO_SIGNAL;
7098
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 //convert to the UI units of 100kbps
7100 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7101
7102#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007103 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 -07007104 sinfo->signal,
7105 pCfg->reportMaxLinkSpeed,
7106 myRate,
7107 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007108 (int) pCfg->linkSpeedRssiMid,
7109 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007110 (int) rate_flags,
7111 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007112#endif //LINKSPEED_DEBUG_ENABLED
7113
7114 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7115 {
7116 // we do not want to necessarily report the current speed
7117 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7118 {
7119 // report the max possible speed
7120 rssidx = 0;
7121 }
7122 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7123 {
7124 // report the max possible speed with RSSI scaling
7125 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7126 {
7127 // report the max possible speed
7128 rssidx = 0;
7129 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007130 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 {
7132 // report middle speed
7133 rssidx = 1;
7134 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007135 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7136 {
7137 // report middle speed
7138 rssidx = 2;
7139 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 else
7141 {
7142 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007143 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 }
7145 }
7146 else
7147 {
7148 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7149 hddLog(VOS_TRACE_LEVEL_ERROR,
7150 "%s: Invalid value for reportMaxLinkSpeed: %u",
7151 __func__, pCfg->reportMaxLinkSpeed);
7152 rssidx = 0;
7153 }
7154
7155 maxRate = 0;
7156
7157 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307158 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7159 OperationalRates, &ORLeng))
7160 {
7161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7162 /*To keep GUI happy*/
7163 return 0;
7164 }
7165
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 for (i = 0; i < ORLeng; i++)
7167 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007168 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 {
7170 /* Validate Rate Set */
7171 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7172 {
7173 currentRate = supported_data_rate[j].supported_rate[rssidx];
7174 break;
7175 }
7176 }
7177 /* Update MAX rate */
7178 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7179 }
7180
7181 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307182 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7183 ExtendedRates, &ERLeng))
7184 {
7185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7186 /*To keep GUI happy*/
7187 return 0;
7188 }
7189
Jeff Johnson295189b2012-06-20 16:38:30 -07007190 for (i = 0; i < ERLeng; i++)
7191 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007192 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 {
7194 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7195 {
7196 currentRate = supported_data_rate[j].supported_rate[rssidx];
7197 break;
7198 }
7199 }
7200 /* Update MAX rate */
7201 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7202 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307203 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307204 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307205 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307206 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307207 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307209 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7210 MCSRates, &MCSLeng))
7211 {
7212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7213 /*To keep GUI happy*/
7214 return 0;
7215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007217#ifdef WLAN_FEATURE_11AC
7218 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307219 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007221 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307222 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007223 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007225 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007227 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007228 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007229 maxMCSIdx = 7;
7230 }
7231 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7232 {
7233 maxMCSIdx = 8;
7234 }
7235 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7236 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307237 //VHT20 is supporting 0~8
7238 if (rate_flags & eHAL_TX_RATE_VHT20)
7239 maxMCSIdx = 8;
7240 else
7241 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007242 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307243
7244 if (rate_flags & eHAL_TX_RATE_VHT80)
7245 {
7246 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7247 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7248 }
7249 else if (rate_flags & eHAL_TX_RATE_VHT40)
7250 {
7251 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7252 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7253 }
7254 else if (rate_flags & eHAL_TX_RATE_VHT20)
7255 {
7256 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7257 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7258 }
7259
Leo Chang6f8870f2013-03-26 18:11:36 -07007260 maxSpeedMCS = 1;
7261 if (currentRate > maxRate)
7262 {
7263 maxRate = currentRate;
7264 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307265
Leo Chang6f8870f2013-03-26 18:11:36 -07007266 }
7267 else
7268#endif /* WLAN_FEATURE_11AC */
7269 {
7270 if (rate_flags & eHAL_TX_RATE_HT40)
7271 {
7272 rateFlag |= 1;
7273 }
7274 if (rate_flags & eHAL_TX_RATE_SGI)
7275 {
7276 rateFlag |= 2;
7277 }
7278
7279 for (i = 0; i < MCSLeng; i++)
7280 {
7281 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7282 for (j = 0; j < temp; j++)
7283 {
7284 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7285 {
7286 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7287 break;
7288 }
7289 }
7290 if ((j < temp) && (currentRate > maxRate))
7291 {
7292 maxRate = currentRate;
7293 maxSpeedMCS = 1;
7294 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7295 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 }
7297 }
7298 }
7299
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307300 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7301 {
7302 maxRate = myRate;
7303 maxSpeedMCS = 1;
7304 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7305 }
7306
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007308 if (((maxRate < myRate) && (0 == rssidx)) ||
7309 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 {
7311 maxRate = myRate;
7312 if (rate_flags & eHAL_TX_RATE_LEGACY)
7313 {
7314 maxSpeedMCS = 0;
7315 }
7316 else
7317 {
7318 maxSpeedMCS = 1;
7319 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7320 }
7321 }
7322
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307323 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 {
7325 sinfo->txrate.legacy = maxRate;
7326#ifdef LINKSPEED_DEBUG_ENABLED
7327 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7328#endif //LINKSPEED_DEBUG_ENABLED
7329 }
7330 else
7331 {
7332 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007333#ifdef WLAN_FEATURE_11AC
7334 sinfo->txrate.nss = 1;
7335 if (rate_flags & eHAL_TX_RATE_VHT80)
7336 {
7337 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307338 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007339 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307340 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007341 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307342 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7343 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7344 }
7345 else if (rate_flags & eHAL_TX_RATE_VHT20)
7346 {
7347 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7348 }
7349#endif /* WLAN_FEATURE_11AC */
7350 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7351 {
7352 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7353 if (rate_flags & eHAL_TX_RATE_HT40)
7354 {
7355 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7356 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 if (rate_flags & eHAL_TX_RATE_SGI)
7359 {
7360 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7361 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307362
Jeff Johnson295189b2012-06-20 16:38:30 -07007363#ifdef LINKSPEED_DEBUG_ENABLED
7364 pr_info("Reporting MCS rate %d flags %x\n",
7365 sinfo->txrate.mcs,
7366 sinfo->txrate.flags );
7367#endif //LINKSPEED_DEBUG_ENABLED
7368 }
7369 }
7370 else
7371 {
7372 // report current rate instead of max rate
7373
7374 if (rate_flags & eHAL_TX_RATE_LEGACY)
7375 {
7376 //provide to the UI in units of 100kbps
7377 sinfo->txrate.legacy = myRate;
7378#ifdef LINKSPEED_DEBUG_ENABLED
7379 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7380#endif //LINKSPEED_DEBUG_ENABLED
7381 }
7382 else
7383 {
7384 //must be MCS
7385 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007386#ifdef WLAN_FEATURE_11AC
7387 sinfo->txrate.nss = 1;
7388 if (rate_flags & eHAL_TX_RATE_VHT80)
7389 {
7390 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7391 }
7392 else
7393#endif /* WLAN_FEATURE_11AC */
7394 {
7395 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 if (rate_flags & eHAL_TX_RATE_SGI)
7398 {
7399 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7400 }
7401 if (rate_flags & eHAL_TX_RATE_HT40)
7402 {
7403 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7404 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007405#ifdef WLAN_FEATURE_11AC
7406 else if (rate_flags & eHAL_TX_RATE_VHT80)
7407 {
7408 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7409 }
7410#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007411#ifdef LINKSPEED_DEBUG_ENABLED
7412 pr_info("Reporting actual MCS rate %d flags %x\n",
7413 sinfo->txrate.mcs,
7414 sinfo->txrate.flags );
7415#endif //LINKSPEED_DEBUG_ENABLED
7416 }
7417 }
7418 sinfo->filled |= STATION_INFO_TX_BITRATE;
7419
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007420 sinfo->tx_packets =
7421 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7422 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7423 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7424 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7425
7426 sinfo->tx_retries =
7427 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7428 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7429 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7430 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7431
7432 sinfo->tx_failed =
7433 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7434 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7435 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7436 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7437
7438 sinfo->filled |=
7439 STATION_INFO_TX_PACKETS |
7440 STATION_INFO_TX_RETRIES |
7441 STATION_INFO_TX_FAILED;
7442
7443 EXIT();
7444 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007445}
7446
7447static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007448 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007449{
7450 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307451 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307453 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007454
Jeff Johnsone7245742012-09-05 17:12:55 -07007455 ENTER();
7456
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 if (NULL == pAdapter)
7458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 return -ENODEV;
7461 }
7462
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307464 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307465
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307466 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307467 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7469 "%s: HDD context is not valid", __func__);
7470 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307471 }
7472
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307473 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7474 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7475 (pHddCtx->cfg_ini->fhostArpOffload) &&
7476 (eConnectionState_Associated ==
7477 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7478 {
Amar Singhald53568e2013-09-26 11:03:45 -07007479
7480 hddLog(VOS_TRACE_LEVEL_INFO,
7481 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307482 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307483 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7484 {
7485 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307487 __func__, vos_status);
7488 }
7489 }
7490
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 /**The get power cmd from the supplicant gets updated by the nl only
7492 *on successful execution of the function call
7493 *we are oppositely mapped w.r.t mode in the driver
7494 **/
7495 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7496
Jeff Johnsone7245742012-09-05 17:12:55 -07007497 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 if (VOS_STATUS_E_FAILURE == vos_status)
7499 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7501 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 return -EINVAL;
7503 }
7504 return 0;
7505}
7506
7507
7508#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7509static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7510 struct net_device *netdev,
7511 u8 key_index)
7512{
Jeff Johnsone7245742012-09-05 17:12:55 -07007513 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 return 0;
7515}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307516#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007517
7518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7519static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7520 struct net_device *dev,
7521 struct ieee80211_txq_params *params)
7522{
Jeff Johnsone7245742012-09-05 17:12:55 -07007523 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 return 0;
7525}
7526#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7527static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7528 struct ieee80211_txq_params *params)
7529{
Jeff Johnsone7245742012-09-05 17:12:55 -07007530 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 return 0;
7532}
7533#endif //LINUX_VERSION_CODE
7534
7535static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7536 struct net_device *dev, u8 *mac)
7537{
7538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007540 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307541 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007542 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007543
Jeff Johnsone7245742012-09-05 17:12:55 -07007544 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307545 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307547 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 return -EINVAL;
7549 }
7550
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307551 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7552 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007553
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007555 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7557 "%s: HDD context is not valid", __func__);
7558 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007559 }
7560
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 )
7564 {
7565 if( NULL == mac )
7566 {
7567 v_U16_t i;
7568 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7569 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007570 if ((pAdapter->aStaInfo[i].isUsed) &&
7571 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 {
7573 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7574 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007575 "%s: Delete STA with MAC::"
7576 MAC_ADDRESS_STR,
7577 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007578 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7579 if (VOS_IS_STATUS_SUCCESS(vos_status))
7580 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 }
7582 }
7583 }
7584 else
7585 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007586
7587 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7588 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7589 {
7590 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007591 "%s: Skip this DEL STA as this is not used::"
7592 MAC_ADDRESS_STR,
7593 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007594 return -ENOENT;
7595 }
7596
7597 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7598 {
7599 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007600 "%s: Skip this DEL STA as deauth is in progress::"
7601 MAC_ADDRESS_STR,
7602 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007603 return -ENOENT;
7604 }
7605
7606 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7607
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 hddLog(VOS_TRACE_LEVEL_INFO,
7609 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007610 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007612 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007613
7614 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7615 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7616 {
7617 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7618 hddLog(VOS_TRACE_LEVEL_INFO,
7619 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007620 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007621 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007622 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007623 return -ENOENT;
7624 }
7625
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 }
7627 }
7628
7629 EXIT();
7630
7631 return 0;
7632}
7633
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007634static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7635 struct net_device *dev, u8 *mac, struct station_parameters *params)
7636{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007637 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007638#ifdef FEATURE_WLAN_TDLS
7639 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007640 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007641 mask = params->sta_flags_mask;
7642
7643 set = params->sta_flags_set;
7644
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007645#ifdef WLAN_FEATURE_TDLS_DEBUG
7646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7647 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7648 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7649#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007650
7651 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7652 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007653 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007654 }
7655 }
7656#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007657 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007658}
7659
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007660
7661#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007662#define MAX_PMKSAIDS_IN_CACHE 8
7663
7664static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7665static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7666
7667
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007668static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007669 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007670{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307671 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7673 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307674 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307675 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007676 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307677 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307678
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007679 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7680 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007681
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307682 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307683 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007684 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007686 return -EINVAL;
7687 }
7688
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307689 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7690 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007691
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307692 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007693 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7695 "%s: HDD context is not valid", __func__);
7696 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007697 }
7698
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307699 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007700 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7701
Wilson Yang6507c4e2013-10-01 20:11:19 -07007702 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007703 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307704 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007705 pmksa->bssid, WNI_CFG_BSSID_LEN))
7706 {
7707 /* BSSID matched previous entry. Overwrite it. */
7708 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307709 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007710 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307711 vos_mem_copy(PMKIDCache[j].PMKID,
7712 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007713 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307714 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007715 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007716 dump_bssid(pmksa->bssid);
7717 dump_pmkid(halHandle, pmksa->pmkid);
7718 break;
7719 }
7720 }
7721
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007722 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007723 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007724
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007725 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307726 {
7727 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007728 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307729 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007730 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307731 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007732 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007734 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007735 dump_bssid(pmksa->bssid);
7736 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307737 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007738 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007739 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007740 }
7741
7742
7743 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307744 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007745 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307746 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007747 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007748 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307749 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7750 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007751 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007752 return 0;
7753}
7754
7755
Wilson Yang6507c4e2013-10-01 20:11:19 -07007756
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007757static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007758 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007759{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007760 tANI_U32 j=0;
7761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7762 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007763 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007764 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007765 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007766
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007767 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7768 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007769
7770 /* Validate pAdapter */
7771 if (NULL == pAdapter)
7772 {
7773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7774 return -EINVAL;
7775 }
7776
7777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7778 status = wlan_hdd_validate_context(pHddCtx);
7779
7780 if (0 != status)
7781 {
7782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7783 "%s: HDD context is not valid", __func__);
7784 return status;
7785 }
7786
7787 /*Retrieve halHandle*/
7788 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7789
7790 /*in case index is 0,no entry to delete*/
7791 if (0 == PMKIDCacheIndex)
7792 {
7793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7794 __func__);
7795 return -EINVAL;
7796 }
7797
7798 /*find the matching PMKSA entry from j=0 to (index-1),
7799 * and delete the matched one
7800 */
7801 for (j = 0; j<PMKIDCacheIndex; j++)
7802 {
7803 if (vos_mem_compare(PMKIDCache[j].BSSID,
7804 pmksa->bssid,
7805 WNI_CFG_BSSID_LEN))
7806 {
7807 /* BSSID matched entry */
7808 BSSIDMatched = 1;
7809
7810 if (j<PMKIDCacheIndex-1)
7811 {
7812 /*replace the matching entry with the last entry in HDD local cache*/
7813 vos_mem_copy(PMKIDCache[j].BSSID,
7814 PMKIDCache[PMKIDCacheIndex-1].BSSID,
7815 WNI_CFG_BSSID_LEN);
7816 vos_mem_copy(PMKIDCache[j].PMKID,
7817 PMKIDCache[PMKIDCacheIndex-1].PMKID,
7818 CSR_RSN_PMKID_SIZE);
7819 }
7820
7821 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07007822 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
7823 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
7824
7825 /*reduce the PMKID array index*/
7826 PMKIDCacheIndex--;
7827
7828 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08007829 if (eHAL_STATUS_SUCCESS !=
7830 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07007831 {
7832 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
7833 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08007834 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007835 }
7836
7837 dump_bssid(pmksa->bssid);
7838 dump_pmkid(halHandle,pmksa->pmkid);
7839
7840 break;
7841 }
7842 }
7843
7844 /* we compare all entries,but cannot find matching entry */
7845 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
7846 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007847 hddLog(VOS_TRACE_LEVEL_FATAL,
7848 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
7849 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007850 dump_bssid(pmksa->bssid);
7851 dump_pmkid(halHandle, pmksa->pmkid);
7852 return -EINVAL;
7853 }
Wilson Yangef657d32014-01-15 19:19:23 -08007854 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007855}
7856
Wilson Yang6507c4e2013-10-01 20:11:19 -07007857
7858
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007859static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7860{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007861 tANI_U32 j=0;
7862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7863 tHalHandle halHandle;
7864 hdd_context_t *pHddCtx;
7865 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08007866 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007867
7868 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
7869
7870 /* Validate pAdapter */
7871 if (NULL == pAdapter)
7872 {
7873 hddLog(VOS_TRACE_LEVEL_ERROR,
7874 "%s: Invalid Adapter" ,__func__);
7875 return -EINVAL;
7876 }
7877
7878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7879 status = wlan_hdd_validate_context(pHddCtx);
7880
7881 if (0 != status)
7882 {
7883 hddLog(VOS_TRACE_LEVEL_ERROR,
7884 "%s: HDD context is not valid", __func__);
7885 return status;
7886 }
7887
7888 /*Retrieve halHandle*/
7889 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7890
7891 /*in case index is 0,no entry to delete*/
7892 if (0 == PMKIDCacheIndex)
7893 {
7894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7895 __func__);
7896 return -EINVAL;
7897 }
7898
7899 /*delete all the PMKSA one by one */
7900 for (j = 0; j<PMKIDCacheIndex; j++)
7901 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07007902 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007903
7904 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08007905 if (eHAL_STATUS_SUCCESS !=
7906 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07007907 {
7908 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
7909 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08007910 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007911 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05307912 /*clear the entry in HDD cache 0--index-1 */
7913 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
7914 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007915 }
7916
7917 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08007918 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007919}
7920#endif
7921
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007922#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307923static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007924 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7925{
7926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7927 hdd_station_ctx_t *pHddStaCtx;
7928
7929 if (NULL == pAdapter)
7930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007931 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007932 return -ENODEV;
7933 }
7934
7935 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7936
7937 // Added for debug on reception of Re-assoc Req.
7938 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7939 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007940 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007941 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007942 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007943 }
7944
7945#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08007946 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007947 ftie->ie_len);
7948#endif
7949
7950 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307951 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7952 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007953 ftie->ie_len);
7954 return 0;
7955}
7956#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007957
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307958#ifdef FEATURE_WLAN_SCAN_PNO
7959
7960void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7961 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7962{
7963 int ret;
7964 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7965 hdd_context_t *pHddCtx;
7966
Nirav Shah80830bf2013-12-31 16:35:12 +05307967 ENTER();
7968
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307969 if (NULL == pAdapter)
7970 {
7971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7972 "%s: HDD adapter is Null", __func__);
7973 return ;
7974 }
7975
7976 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7977 if (NULL == pHddCtx)
7978 {
7979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7980 "%s: HDD context is Null!!!", __func__);
7981 return ;
7982 }
7983
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05307984 spin_lock(&pHddCtx->schedScan_lock);
7985 if (TRUE == pHddCtx->isWiphySuspended)
7986 {
7987 pHddCtx->isSchedScanUpdatePending = TRUE;
7988 spin_unlock(&pHddCtx->schedScan_lock);
7989 hddLog(VOS_TRACE_LEVEL_INFO,
7990 "%s: Update cfg80211 scan database after it resume", __func__);
7991 return ;
7992 }
7993 spin_unlock(&pHddCtx->schedScan_lock);
7994
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307995 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7996
7997 if (0 > ret)
7998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7999
8000 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8002 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308003}
8004
8005/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308006 * FUNCTION: wlan_hdd_is_pno_allowed
8007 * To check is there any P2P GO/SAP or P2P Client/STA
8008 * session is active
8009 */
8010static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8011{
8012 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8013 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308014 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308015 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8016 int status = 0;
8017 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8018
8019 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8020 {
8021 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308022 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308023
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308024 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8025 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8026 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8027 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8028 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8029 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308030 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308031 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308032 }
8033 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8034 pAdapterNode = pNext;
8035 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308036 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308037}
8038
8039/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308040 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8041 * NL interface to enable PNO
8042 */
8043static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8044 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8045{
8046 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8047 tpSirPNOScanReq pPnoRequest = NULL;
8048 hdd_context_t *pHddCtx;
8049 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308050 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308051 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8052 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8053 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8054 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308055 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308056
8057 if (NULL == pAdapter)
8058 {
8059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8060 "%s: HDD adapter is Null", __func__);
8061 return -ENODEV;
8062 }
8063
8064 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308065 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308066
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308067 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308068 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8070 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308071 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308072 }
8073
8074 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8075 if (NULL == hHal)
8076 {
8077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8078 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308079 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308080 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308081
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308082 /* The current firmware design for PNO does not consider concurrent
8083 * active sessions.Hence , determine the concurrent active sessions
8084 * and return a failure to the framework on a request for schedule
8085 * scan.
8086 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308087 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308088 {
8089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308090 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308091 return -EBUSY;
8092 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308093
8094 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8095 if (NULL == pPnoRequest)
8096 {
8097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8098 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308099 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308100 }
8101
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308102 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308103 pPnoRequest->enable = 1; /*Enable PNO */
8104 pPnoRequest->ucNetworksCount = request->n_match_sets;
8105
8106 if (( !pPnoRequest->ucNetworksCount ) ||
8107 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8108 {
8109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308110 "%s: Network input is not correct %d",
8111 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308112 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308113 goto error;
8114 }
8115
8116 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8117 {
8118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308119 "%s: Incorrect number of channels %d",
8120 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308121 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308122 goto error;
8123 }
8124
8125 /* Framework provides one set of channels(all)
8126 * common for all saved profile */
8127 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8128 channels_allowed, &num_channels_allowed))
8129 {
8130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8131 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308132 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308133 goto error;
8134 }
8135 /* Checking each channel against allowed channel list */
8136 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308137 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308138 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308139 char chList [(request->n_channels*5)+1];
8140 int len;
8141 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308142 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308143 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308144 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308145 if (request->channels[i]->hw_value == channels_allowed[indx])
8146 {
8147 valid_ch[num_ch++] = request->channels[i]->hw_value;
8148 len += snprintf(chList+len, 5, "%d ",
8149 request->channels[i]->hw_value);
8150 break ;
8151 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308152 }
8153 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308154 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8155 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308156
8157 /* Filling per profile params */
8158 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8159 {
8160 pPnoRequest->aNetworks[i].ssId.length =
8161 request->match_sets[i].ssid.ssid_len;
8162
8163 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8164 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8165 {
8166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308167 "%s: SSID Len %d is not correct for network %d",
8168 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308169 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308170 goto error;
8171 }
8172
8173 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8174 request->match_sets[i].ssid.ssid,
8175 request->match_sets[i].ssid.ssid_len);
8176 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8177 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8178 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8179
8180 /*Copying list of valid channel into request */
8181 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8182 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8183
8184 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8185 }
8186
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008188 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308189 if ((0 < request->ie_len) && (NULL != request->ie))
8190 {
8191 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8192 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8193 pPnoRequest->us24GProbeTemplateLen);
8194
8195 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8196 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8197 pPnoRequest->us5GProbeTemplateLen);
8198 }
8199
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308200 /* Driver gets only one time interval which is hardcoded in
8201 * supplicant for 10000ms. Taking power consumption into account 6 timers
8202 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8203 * 80,160,320 secs. And number of scan cycle for each timer
8204 * is configurable through INI param gPNOScanTimerRepeatValue.
8205 * If it is set to 0 only one timer will be used and PNO scan cycle
8206 * will be repeated after each interval specified by supplicant
8207 * till PNO is disabled.
8208 */
8209 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8210 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8211 else
8212 pPnoRequest->scanTimers.ucScanTimersCount =
8213 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8214
8215 tempInterval = (request->interval)/1000;
8216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8217 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8218 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8219 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8220 {
8221 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8222 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8223 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8224 tempInterval *= 2;
8225 }
8226 //Repeat last timer until pno disabled.
8227 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8228
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308229 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308230
Nirav Shah80830bf2013-12-31 16:35:12 +05308231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8232 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8233 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8234 pPnoRequest->scanTimers.ucScanTimersCount);
8235
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308236 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8237 pPnoRequest, pAdapter->sessionId,
8238 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8239 if (eHAL_STATUS_SUCCESS != status)
8240 {
8241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308242 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308243 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308244 goto error;
8245 }
8246
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8248 "PNO scanRequest offloaded");
8249
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308250error:
8251 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308252 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308253}
8254
8255/*
8256 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8257 * NL interface to disable PNO
8258 */
8259static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8260 struct net_device *dev)
8261{
8262 eHalStatus status = eHAL_STATUS_FAILURE;
8263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8264 hdd_context_t *pHddCtx;
8265 tHalHandle hHal;
8266 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308267 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308268
8269 ENTER();
8270
8271 if (NULL == pAdapter)
8272 {
8273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8274 "%s: HDD adapter is Null", __func__);
8275 return -ENODEV;
8276 }
8277
8278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308279
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308280 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308281 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308283 "%s: HDD context is Null", __func__);
8284 return -ENODEV;
8285 }
8286
8287 /* The return 0 is intentional when isLogpInProgress and
8288 * isLoadUnloadInProgress. We did observe a crash due to a return of
8289 * failure in sched_scan_stop , especially for a case where the unload
8290 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8291 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8292 * success. If it returns a failure , then its next invocation due to the
8293 * clean up of the second interface will have the dev pointer corresponding
8294 * to the first one leading to a crash.
8295 */
8296 if (pHddCtx->isLogpInProgress)
8297 {
8298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8299 "%s: LOGP in Progress. Ignore!!!", __func__);
8300 return ret;
8301 }
8302
8303 if (pHddCtx->isLoadUnloadInProgress)
8304 {
8305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8306 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8307 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308308 }
8309
8310 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8311 if (NULL == hHal)
8312 {
8313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8314 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308315 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308316 }
8317
8318 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8319 if (NULL == pPnoRequest)
8320 {
8321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8322 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308323 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308324 }
8325
8326 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8327 pPnoRequest->enable = 0; /* Disable PNO */
8328 pPnoRequest->ucNetworksCount = 0;
8329
8330 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8331 pAdapter->sessionId,
8332 NULL, pAdapter);
8333 if (eHAL_STATUS_SUCCESS != status)
8334 {
8335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8336 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308337 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308338 }
8339
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8341 "%s: PNO scan disabled", __func__);
8342
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308343 vos_mem_free(pPnoRequest);
8344
8345 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308346 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308347}
8348
8349#endif /*FEATURE_WLAN_SCAN_PNO*/
8350
8351
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008352#ifdef FEATURE_WLAN_TDLS
8353static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8354 u8 *peer, u8 action_code, u8 dialog_token,
8355 u16 status_code, const u8 *buf, size_t len)
8356{
8357
8358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8359 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008360 u8 peerMac[6];
8361 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008362 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008363 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008364 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008365
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008366 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008369 "Invalid arguments");
8370 return -EINVAL;
8371 }
8372
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008373 if (pHddCtx->isLogpInProgress)
8374 {
8375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8376 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008377 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008378 return -EBUSY;
8379 }
8380
Hoonki Lee27511902013-03-14 18:19:06 -07008381 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008382 {
Hoonki Lee27511902013-03-14 18:19:06 -07008383 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8384 "%s: TDLS mode is disabled OR not enabled in FW."
8385 MAC_ADDRESS_STR " action %d declined.",
8386 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008387 return -ENOTSUPP;
8388 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008389
Hoonki Lee27511902013-03-14 18:19:06 -07008390 /* other than teardown frame, other mgmt frames are not sent if disabled */
8391 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8392 {
8393 /* if tdls_mode is disabled to respond to peer's request */
8394 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8395 {
8396 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8397 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008398 " TDLS mode is disabled. action %d declined.",
8399 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008400
8401 return -ENOTSUPP;
8402 }
8403 }
8404
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008405 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8406 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308407 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008408 {
8409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008410 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008411 " TDLS setup is ongoing. action %d declined.",
8412 __func__, MAC_ADDR_ARRAY(peer), action_code);
8413 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008414 }
8415 }
8416
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008417 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8418 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008419 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008420 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008421 {
8422 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8423 we return error code at 'add_station()'. Hence we have this
8424 check again in addtion to add_station().
8425 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008426 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008427 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8429 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008430 " TDLS Max peer already connected. action %d declined.",
8431 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308432 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008433 }
8434 else
8435 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008436 /* maximum reached. tweak to send error code to peer and return
8437 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008438 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8440 "%s: " MAC_ADDRESS_STR
8441 " TDLS Max peer already connected send response status %d",
8442 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008443 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008444 /* fall through to send setup resp with failure status
8445 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008446 }
8447 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008448 else
8449 {
8450 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308451 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008452 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008453 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008455 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8456 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008457 return -EPERM;
8458 }
8459 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008460 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008461 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008462
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008463#ifdef WLAN_FEATURE_TDLS_DEBUG
8464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008465 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8466 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8467 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008468#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008469
Hoonki Leea34dd892013-02-05 22:56:02 -08008470 /*Except teardown responder will not be used so just make 0*/
8471 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008472 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008473 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008474
8475 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308476 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008477
8478 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8479 responder = pTdlsPeer->is_responder;
8480 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008481 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8483 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8484 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8485 dialog_token, status_code, len);
8486 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008487 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008488 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008489
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308490 /* For explicit trigger of DIS_REQ come out of BMPS for
8491 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008492 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308493 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8494 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008495 {
8496 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8497 {
8498 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308499 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008500 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8501 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308502 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8503 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008504 }
8505
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008506 /* make sure doesn't call send_mgmt() while it is pending */
8507 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8508 {
8509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008510 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008511 __func__, MAC_ADDR_ARRAY(peer), action_code);
8512 return -EBUSY;
8513 }
8514
8515 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008516 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8517
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008518 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008519 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008520
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008521 if (VOS_STATUS_SUCCESS != status)
8522 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8524 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008525 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008526 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308527 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008528 }
8529
Hoonki Leed37cbb32013-04-20 00:31:14 -07008530 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8531 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8532
8533 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008534 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008536 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008537 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008538 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008539
8540 if (pHddCtx->isLogpInProgress)
8541 {
8542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8543 "%s: LOGP in Progress. Ignore!!!", __func__);
8544 return -EAGAIN;
8545 }
8546
Hoonki Leed37cbb32013-04-20 00:31:14 -07008547 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308548 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008549 }
8550
Gopichand Nakkala05922802013-03-14 12:23:19 -07008551 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008552 {
8553 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008554 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008555 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008556
Hoonki Leea34dd892013-02-05 22:56:02 -08008557 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8558 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008559 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008560 }
8561 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8562 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008563 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008564 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008565
8566 return 0;
8567}
8568
8569static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8570 u8 *peer, enum nl80211_tdls_operation oper)
8571{
8572 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8573 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308574 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008575 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008576
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308577 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008578 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008580 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008581 return -EINVAL;
8582 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008583
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308584 status = wlan_hdd_validate_context(pHddCtx);
8585
8586 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008587 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8589 "%s: HDD context is not valid", __func__);
8590 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008591 }
8592
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008593
8594 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008595 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008596 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008598 "TDLS Disabled in INI OR not enabled in FW. "
8599 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008600 return -ENOTSUPP;
8601 }
8602
8603 switch (oper) {
8604 case NL80211_TDLS_ENABLE_LINK:
8605 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008606 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308607 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308608 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008609
Sunil Dutt41de4e22013-11-14 18:09:02 +05308610 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8611
8612 if ( NULL == pTdlsPeer ) {
8613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8614 " (oper %d) not exsting. ignored",
8615 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8616 return -EINVAL;
8617 }
8618
8619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8620 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8621 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8622 "NL80211_TDLS_ENABLE_LINK");
8623
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008624 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8625 {
8626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8627 MAC_ADDRESS_STR " failed",
8628 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8629 return -EINVAL;
8630 }
8631
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008632 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008633 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308634 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308635
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308636 if (0 != wlan_hdd_tdls_get_link_establish_params(
8637 pAdapter, peer,&tdlsLinkEstablishParams)) {
8638 return -EINVAL;
8639 }
8640 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308641
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308642 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8643 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8644 /* Send TDLS peer UAPSD capabilities to the firmware and
8645 * register with the TL on after the response for this operation
8646 * is received .
8647 */
8648 ret = wait_for_completion_interruptible_timeout(
8649 &pAdapter->tdls_link_establish_req_comp,
8650 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8651 if (ret <= 0)
8652 {
8653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8654 "%s: Link Establish Request Faled Status %ld",
8655 __func__, ret);
8656 return -EINVAL;
8657 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308658 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008659 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308660 /* Mark TDLS client Authenticated .*/
8661 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8662 pTdlsPeer->staId,
8663 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008664 if (VOS_STATUS_SUCCESS == status)
8665 {
Hoonki Lee14621352013-04-16 17:51:19 -07008666 if (pTdlsPeer->is_responder == 0)
8667 {
8668 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8669
8670 wlan_hdd_tdls_timer_restart(pAdapter,
8671 &pTdlsPeer->initiatorWaitTimeoutTimer,
8672 WAIT_TIME_TDLS_INITIATOR);
8673 /* suspend initiator TX until it receives direct packet from the
8674 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8675 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8676 &staId, NULL);
8677 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008678 wlan_hdd_tdls_increment_peer_count(pAdapter);
8679 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008680 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308681
8682 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308683 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8684 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308685 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308686 int ac;
8687 uint8 ucAc[4] = { WLANTL_AC_VO,
8688 WLANTL_AC_VI,
8689 WLANTL_AC_BK,
8690 WLANTL_AC_BE };
8691 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8692 for(ac=0; ac < 4; ac++)
8693 {
8694 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8695 pTdlsPeer->staId, ucAc[ac],
8696 tlTid[ac], tlTid[ac], 0, 0,
8697 WLANTL_BI_DIR );
8698 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308699 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008700 }
8701
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008702 }
8703 break;
8704 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008705 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308706 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8707
8708 if ( NULL == pTdlsPeer ) {
8709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8710 " (oper %d) not exsting. ignored",
8711 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8712 return -EINVAL;
8713 }
8714
8715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8716 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8717 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8718 "NL80211_TDLS_DISABLE_LINK");
8719
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008720 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008721 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008722 long status;
8723
8724 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8725
Lee Hoonkic1262f22013-01-24 21:59:00 -08008726 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8727 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008728
8729 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8730 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8731 if (status <= 0)
8732 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008733 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8735 "%s: Del station failed status %ld",
8736 __func__, status);
8737 return -EPERM;
8738 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008739 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008740 }
8741 else
8742 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8744 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008745 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008746 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008747 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008748 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308749 {
8750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8751 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8752 __func__, MAC_ADDR_ARRAY(peer));
8753
8754 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8755 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8756
8757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8758 " %s TDLS External control and Implicit Trigger not enabled ",
8759 __func__);
8760 return -ENOTSUPP;
8761 }
8762
Sunil Dutt41de4e22013-11-14 18:09:02 +05308763
8764 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8765
8766 if ( NULL == pTdlsPeer ) {
8767 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8768 " peer not exsting",
8769 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308770 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308771 }
8772 else {
8773 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8774 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8775 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308776
8777 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8778 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308779 break;
8780 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008781 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308782 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308783 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8785 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8786 __func__, MAC_ADDR_ARRAY(peer));
8787
8788 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8789 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8790
8791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8792 " %s TDLS External control and Implicit Trigger not enabled ",
8793 __func__);
8794 return -ENOTSUPP;
8795 }
8796
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308797 /* To cater the requirement of establishing the TDLS link
8798 * irrespective of the data traffic , get an entry of TDLS peer.
8799 */
8800 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8801 if (pTdlsPeer == NULL) {
8802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8803 "%s: peer " MAC_ADDRESS_STR " not existing",
8804 __func__, MAC_ADDR_ARRAY(peer));
8805 return -EINVAL;
8806 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308807
8808 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
8809
8810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8811 " %s TDLS Add Force Peer Failed",
8812 __func__);
8813 return -EINVAL;
8814 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308815 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308816 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008817 case NL80211_TDLS_DISCOVERY_REQ:
8818 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8820 "%s: We don't support in-driver setup/teardown/discovery "
8821 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008822 return -ENOTSUPP;
8823 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8825 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008826 return -ENOTSUPP;
8827 }
8828 return 0;
8829}
Chilam NG571c65a2013-01-19 12:27:36 +05308830
8831int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
8832 struct net_device *dev, u8 *peer)
8833{
Arif Hussaina7c8e412013-11-20 11:06:42 -08008834 hddLog(VOS_TRACE_LEVEL_INFO,
8835 "tdls send discover req: "MAC_ADDRESS_STR,
8836 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05308837
8838 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
8839 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
8840}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008841#endif
8842
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308843#ifdef WLAN_FEATURE_GTK_OFFLOAD
8844/*
8845 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
8846 * Callback rountine called upon receiving response for
8847 * get offload info
8848 */
8849void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
8850 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
8851{
8852
8853 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308854 tANI_U8 tempReplayCounter[8];
8855 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308856
8857 ENTER();
8858
8859 if (NULL == pAdapter)
8860 {
8861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8862 "%s: HDD adapter is Null", __func__);
8863 return ;
8864 }
8865
8866 if (NULL == pGtkOffloadGetInfoRsp)
8867 {
8868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8869 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
8870 return ;
8871 }
8872
8873 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
8874 {
8875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8876 "%s: wlan Failed to get replay counter value",
8877 __func__);
8878 return ;
8879 }
8880
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8882 /* Update replay counter */
8883 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
8884 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
8885
8886 {
8887 /* changing from little to big endian since supplicant
8888 * works on big endian format
8889 */
8890 int i;
8891 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
8892
8893 for (i = 0; i < 8; i++)
8894 {
8895 tempReplayCounter[7-i] = (tANI_U8)p[i];
8896 }
8897 }
8898
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308899 /* Update replay counter to NL */
8900 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308901 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308902}
8903
8904/*
8905 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
8906 * This function is used to offload GTK rekeying job to the firmware.
8907 */
8908int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
8909 struct cfg80211_gtk_rekey_data *data)
8910{
8911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8912 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8913 hdd_station_ctx_t *pHddStaCtx;
8914 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308915 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308916 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308917 eHalStatus status = eHAL_STATUS_FAILURE;
8918
8919 ENTER();
8920
8921 if (NULL == pAdapter)
8922 {
8923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8924 "%s: HDD adapter is Null", __func__);
8925 return -ENODEV;
8926 }
8927
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308928 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308929
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308930 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308931 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8933 "%s: HDD context is not valid", __func__);
8934 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308935 }
8936
8937 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8938 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8939 if (NULL == hHal)
8940 {
8941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8942 "%s: HAL context is Null!!!", __func__);
8943 return -EAGAIN;
8944 }
8945
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308946 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
8947 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
8948 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
8949 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308950 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308951 {
8952 /* changing from big to little endian since driver
8953 * works on little endian format
8954 */
8955 tANI_U8 *p =
8956 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
8957 int i;
8958
8959 for (i = 0; i < 8; i++)
8960 {
8961 p[7-i] = data->replay_ctr[i];
8962 }
8963 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308964
8965 if (TRUE == pHddCtx->hdd_wlan_suspended)
8966 {
8967 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308968 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
8969 sizeof (tSirGtkOffloadParams));
8970 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308971 pAdapter->sessionId);
8972
8973 if (eHAL_STATUS_SUCCESS != status)
8974 {
8975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8976 "%s: sme_SetGTKOffload failed, returned %d",
8977 __func__, status);
8978 return status;
8979 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8981 "%s: sme_SetGTKOffload successfull", __func__);
8982 }
8983 else
8984 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8986 "%s: wlan not suspended GTKOffload request is stored",
8987 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308988 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308989
8990 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308991}
8992#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
8993
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308994/*
8995 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
8996 * This function is used to set access control policy
8997 */
8998static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
8999 struct net_device *dev, const struct cfg80211_acl_data *params)
9000{
9001 int i;
9002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9003 hdd_hostapd_state_t *pHostapdState;
9004 tsap_Config_t *pConfig;
9005 v_CONTEXT_t pVosContext = NULL;
9006 hdd_context_t *pHddCtx;
9007 int status;
9008
9009 ENTER();
9010
9011 if (NULL == pAdapter)
9012 {
9013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9014 "%s: HDD adapter is Null", __func__);
9015 return -ENODEV;
9016 }
9017
9018 if (NULL == params)
9019 {
9020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9021 "%s: params is Null", __func__);
9022 return -EINVAL;
9023 }
9024
9025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9026 status = wlan_hdd_validate_context(pHddCtx);
9027
9028 if (0 != status)
9029 {
9030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9031 "%s: HDD context is not valid", __func__);
9032 return status;
9033 }
9034
9035 pVosContext = pHddCtx->pvosContext;
9036 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9037
9038 if (NULL == pHostapdState)
9039 {
9040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9041 "%s: pHostapdState is Null", __func__);
9042 return -EINVAL;
9043 }
9044
9045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9046 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9047
9048 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9049 {
9050 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9051
9052 /* default value */
9053 pConfig->num_accept_mac = 0;
9054 pConfig->num_deny_mac = 0;
9055
9056 /**
9057 * access control policy
9058 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9059 * listed in hostapd.deny file.
9060 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9061 * listed in hostapd.accept file.
9062 */
9063 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9064 {
9065 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9066 }
9067 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9068 {
9069 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9070 }
9071 else
9072 {
9073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9074 "%s:Acl Policy : %d is not supported",
9075 __func__, params->acl_policy);
9076 return -ENOTSUPP;
9077 }
9078
9079 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9080 {
9081 pConfig->num_accept_mac = params->n_acl_entries;
9082 for (i = 0; i < params->n_acl_entries; i++)
9083 {
9084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9085 "** Add ACL MAC entry %i in WhiletList :"
9086 MAC_ADDRESS_STR, i,
9087 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9088
9089 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9090 sizeof(qcmacaddr));
9091 }
9092 }
9093 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9094 {
9095 pConfig->num_deny_mac = params->n_acl_entries;
9096 for (i = 0; i < params->n_acl_entries; i++)
9097 {
9098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9099 "** Add ACL MAC entry %i in BlackList :"
9100 MAC_ADDRESS_STR, i,
9101 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9102
9103 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9104 sizeof(qcmacaddr));
9105 }
9106 }
9107
9108 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9109 {
9110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9111 "%s: SAP Set Mac Acl fail", __func__);
9112 return -EINVAL;
9113 }
9114 }
9115 else
9116 {
9117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9118 "%s: Invalid device_mode = %d",
9119 __func__, pAdapter->device_mode);
9120 return -EINVAL;
9121 }
9122
9123 return 0;
9124}
9125
Leo Chang9056f462013-08-01 19:21:11 -07009126#ifdef WLAN_NL80211_TESTMODE
9127#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009128void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009129(
9130 void *pAdapter,
9131 void *indCont
9132)
9133{
Leo Changd9df8aa2013-09-26 13:32:26 -07009134 tSirLPHBInd *lphbInd;
9135 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009136
9137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009138 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009139
9140 if (NULL == indCont)
9141 {
9142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009143 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009144 return;
9145 }
9146
Leo Changd9df8aa2013-09-26 13:32:26 -07009147 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009148 skb = cfg80211_testmode_alloc_event_skb(
9149 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009150 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009151 GFP_ATOMIC);
9152 if (!skb)
9153 {
9154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9155 "LPHB timeout, NL buffer alloc fail");
9156 return;
9157 }
9158
Leo Changac3ba772013-10-07 09:47:04 -07009159 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009160 {
9161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9162 "WLAN_HDD_TM_ATTR_CMD put fail");
9163 goto nla_put_failure;
9164 }
Leo Changac3ba772013-10-07 09:47:04 -07009165 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009166 {
9167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9168 "WLAN_HDD_TM_ATTR_TYPE put fail");
9169 goto nla_put_failure;
9170 }
Leo Changac3ba772013-10-07 09:47:04 -07009171 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009172 sizeof(tSirLPHBInd), lphbInd))
9173 {
9174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9175 "WLAN_HDD_TM_ATTR_DATA put fail");
9176 goto nla_put_failure;
9177 }
Leo Chang9056f462013-08-01 19:21:11 -07009178 cfg80211_testmode_event(skb, GFP_ATOMIC);
9179 return;
9180
9181nla_put_failure:
9182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9183 "NLA Put fail");
9184 kfree_skb(skb);
9185
9186 return;
9187}
9188#endif /* FEATURE_WLAN_LPHB */
9189
9190static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9191{
9192 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9193 int err = 0;
9194#ifdef FEATURE_WLAN_LPHB
9195 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009196 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009197#endif /* FEATURE_WLAN_LPHB */
9198
9199 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9200 if (err)
9201 {
9202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9203 "%s Testmode INV ATTR", __func__);
9204 return err;
9205 }
9206
9207 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9208 {
9209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9210 "%s Testmode INV CMD", __func__);
9211 return -EINVAL;
9212 }
9213
9214 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9215 {
9216#ifdef FEATURE_WLAN_LPHB
9217 /* Low Power Heartbeat configuration request */
9218 case WLAN_HDD_TM_CMD_WLAN_HB:
9219 {
9220 int buf_len;
9221 void *buf;
9222 tSirLPHBReq *hb_params = NULL;
9223
9224 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9225 {
9226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9227 "%s Testmode INV DATA", __func__);
9228 return -EINVAL;
9229 }
9230
9231 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9232 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
9233 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9234 if (NULL == hb_params)
9235 {
9236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9237 "%s Request Buffer Alloc Fail", __func__);
9238 return -EINVAL;
9239 }
9240
9241 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009242 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9243 hb_params,
9244 wlan_hdd_cfg80211_lphb_ind_handler);
9245 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009246 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9248 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009249 vos_mem_free(hb_params);
9250 }
Leo Chang9056f462013-08-01 19:21:11 -07009251 return 0;
9252 }
9253#endif /* FEATURE_WLAN_LPHB */
9254 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9256 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009257 return -EOPNOTSUPP;
9258 }
9259
9260 return err;
9261}
9262#endif /* CONFIG_NL80211_TESTMODE */
9263
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309264static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9265 struct net_device *dev,
9266 int idx, struct survey_info *survey)
9267{
9268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9269 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309270 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309271 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309272 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309273 v_S7_t snr,rssi;
9274 int status, i, j, filled = 0;
9275
9276 ENTER();
9277
9278
9279 if (NULL == pAdapter)
9280 {
9281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9282 "%s: HDD adapter is Null", __func__);
9283 return -ENODEV;
9284 }
9285
9286 if (NULL == wiphy)
9287 {
9288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9289 "%s: wiphy is Null", __func__);
9290 return -ENODEV;
9291 }
9292
9293 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9294 status = wlan_hdd_validate_context(pHddCtx);
9295
9296 if (0 != status)
9297 {
9298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9299 "%s: HDD context is not valid", __func__);
9300 return status;
9301 }
9302
Mihir Sheted9072e02013-08-21 17:02:29 +05309303 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9304
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309305 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309306 0 != pAdapter->survey_idx ||
9307 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309308 {
9309 /* The survey dump ops when implemented completely is expected to
9310 * return a survey of all channels and the ops is called by the
9311 * kernel with incremental values of the argument 'idx' till it
9312 * returns -ENONET. But we can only support the survey for the
9313 * operating channel for now. survey_idx is used to track
9314 * that the ops is called only once and then return -ENONET for
9315 * the next iteration
9316 */
9317 pAdapter->survey_idx = 0;
9318 return -ENONET;
9319 }
9320
9321 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9322
9323 wlan_hdd_get_snr(pAdapter, &snr);
9324 wlan_hdd_get_rssi(pAdapter, &rssi);
9325
9326 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9327 hdd_wlan_get_freq(channel, &freq);
9328
9329
9330 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9331 {
9332 if (NULL == wiphy->bands[i])
9333 {
9334 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9335 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9336 continue;
9337 }
9338
9339 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9340 {
9341 struct ieee80211_supported_band *band = wiphy->bands[i];
9342
9343 if (band->channels[j].center_freq == (v_U16_t)freq)
9344 {
9345 survey->channel = &band->channels[j];
9346 /* The Rx BDs contain SNR values in dB for the received frames
9347 * while the supplicant expects noise. So we calculate and
9348 * return the value of noise (dBm)
9349 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9350 */
9351 survey->noise = rssi - snr;
9352 survey->filled = SURVEY_INFO_NOISE_DBM;
9353 filled = 1;
9354 }
9355 }
9356 }
9357
9358 if (filled)
9359 pAdapter->survey_idx = 1;
9360 else
9361 {
9362 pAdapter->survey_idx = 0;
9363 return -ENONET;
9364 }
9365
9366 return 0;
9367}
9368
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309369/*
9370 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9371 * this is called when cfg80211 driver resume
9372 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9373 */
9374int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9375{
9376 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9377 hdd_adapter_t *pAdapter;
9378 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9379 VOS_STATUS status = VOS_STATUS_SUCCESS;
9380
9381 ENTER();
9382
9383 if ( NULL == pHddCtx )
9384 {
9385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9386 "%s: HddCtx validation failed", __func__);
9387 return 0;
9388 }
9389
9390 if (pHddCtx->isLogpInProgress)
9391 {
9392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9393 "%s: LOGP in Progress. Ignore!!!", __func__);
9394 return 0;
9395 }
9396
9397 if (pHddCtx->isLoadUnloadInProgress)
9398 {
9399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9400 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9401 return 0;
9402 }
9403
9404 spin_lock(&pHddCtx->schedScan_lock);
9405 pHddCtx->isWiphySuspended = FALSE;
9406 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9407 {
9408 spin_unlock(&pHddCtx->schedScan_lock);
9409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9410 "%s: Return resume is not due to PNO indication", __func__);
9411 return 0;
9412 }
9413 // Reset flag to avoid updatating cfg80211 data old results again
9414 pHddCtx->isSchedScanUpdatePending = FALSE;
9415 spin_unlock(&pHddCtx->schedScan_lock);
9416
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309417
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309418 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9419
9420 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9421 {
9422 pAdapter = pAdapterNode->pAdapter;
9423 if ( (NULL != pAdapter) &&
9424 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9425 {
9426 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309427 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9429 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309430 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309431 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309432 {
9433 /* Acquire wakelock to handle the case where APP's tries to
9434 * suspend immediately after updating the scan results. Whis
9435 * results in app's is in suspended state and not able to
9436 * process the connect request to AP
9437 */
9438 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309439 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309440 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309441
9442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9443 "%s : cfg80211 scan result database updated", __func__);
9444
9445 return 0;
9446
9447 }
9448 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9449 pAdapterNode = pNext;
9450 }
9451
9452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9453 "%s: Failed to find Adapter", __func__);
9454 return 0;
9455}
9456
9457/*
9458 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9459 * this is called when cfg80211 driver suspends
9460 */
9461int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9462 struct cfg80211_wowlan *wow)
9463{
9464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9465
9466 ENTER();
9467 if (NULL == pHddCtx)
9468 {
9469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9470 "%s: HddCtx validation failed", __func__);
9471 return 0;
9472 }
9473
9474 pHddCtx->isWiphySuspended = TRUE;
9475
9476 EXIT();
9477
9478 return 0;
9479}
9480
Jeff Johnson295189b2012-06-20 16:38:30 -07009481/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009483{
9484 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9485 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9486 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9487 .change_station = wlan_hdd_change_station,
9488#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9489 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9490 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9491 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009492#else
9493 .start_ap = wlan_hdd_cfg80211_start_ap,
9494 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9495 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009496#endif
9497 .change_bss = wlan_hdd_cfg80211_change_bss,
9498 .add_key = wlan_hdd_cfg80211_add_key,
9499 .get_key = wlan_hdd_cfg80211_get_key,
9500 .del_key = wlan_hdd_cfg80211_del_key,
9501 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009502#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009504#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 .scan = wlan_hdd_cfg80211_scan,
9506 .connect = wlan_hdd_cfg80211_connect,
9507 .disconnect = wlan_hdd_cfg80211_disconnect,
9508 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9509 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9510 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9511 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9512 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9514 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9515 .mgmt_tx = wlan_hdd_action,
9516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9517 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9518 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9519 .set_txq_params = wlan_hdd_set_txq_params,
9520#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 .get_station = wlan_hdd_cfg80211_get_station,
9522 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9523 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009524 .add_station = wlan_hdd_cfg80211_add_station,
9525#ifdef FEATURE_WLAN_LFR
9526 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9527 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9528 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9529#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009530#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9531 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9532#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009533#ifdef FEATURE_WLAN_TDLS
9534 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9535 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9536#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309537#ifdef WLAN_FEATURE_GTK_OFFLOAD
9538 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9539#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309540#ifdef FEATURE_WLAN_SCAN_PNO
9541 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9542 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9543#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309544 .resume = wlan_hdd_cfg80211_resume_wlan,
9545 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309546 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009547#ifdef WLAN_NL80211_TESTMODE
9548 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9549#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309550 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009551};
9552