blob: 936b47a0c56d39c620a3f98cc47008e1c9b8b50a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20*/
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22/**========================================================================
23
24 \file wlan_hdd_cfg80211.c
25
26 \brief WLAN Host Device Driver implementation
27
Gopichand Nakkala747461f2013-04-24 19:24:45 +053028 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053030 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32 ========================================================================*/
33
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070034/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070035
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070036 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070046 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070047 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070052 ==========================================================================*/
53
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include <linux/version.h>
56#include <linux/module.h>
57#include <linux/kernel.h>
58#include <linux/init.h>
59#include <linux/wireless.h>
60#include <wlan_hdd_includes.h>
61#include <net/arp.h>
62#include <net/cfg80211.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_wowl.h>
65#include <aniGlobal.h>
66#include "ccmApi.h"
67#include "sirParams.h"
68#include "dot11f.h"
69#include "wlan_hdd_assoc.h"
70#include "wlan_hdd_wext.h"
71#include "sme_Api.h"
72#include "wlan_hdd_p2p.h"
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_hostapd.h"
75#include "sapInternal.h"
76#include "wlan_hdd_softap_tx_rx.h"
77#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053078#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053079#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080#ifdef WLAN_BTAMP_FEATURE
81#include "bap_hdd_misc.h"
82#endif
83#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053086#include "wlan_hdd_wmm.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080087#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053088#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070089#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090
91#define g_mode_rates_size (12)
92#define a_mode_rates_size (8)
93#define FREQ_BASE_80211G (2407)
94#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070095#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070096#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
97 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
98
99#define HDD2GHZCHAN(freq, chan, flag) { \
100 .band = IEEE80211_BAND_2GHZ, \
101 .center_freq = (freq), \
102 .hw_value = (chan),\
103 .flags = (flag), \
104 .max_antenna_gain = 0 ,\
105 .max_power = 30, \
106}
107
108#define HDD5GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_5GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
118{\
119 .bitrate = rate, \
120 .hw_value = rate_id, \
121 .flags = flag, \
122}
123
Lee Hoonkic1262f22013-01-24 21:59:00 -0800124#ifndef WLAN_FEATURE_TDLS_DEBUG
125#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
126#else
127#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
128#endif
129
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530130#ifdef WLAN_FEATURE_VOWIFI_11R
131#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
132#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
133#endif
134
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530135static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700136{
137 WLAN_CIPHER_SUITE_WEP40,
138 WLAN_CIPHER_SUITE_WEP104,
139 WLAN_CIPHER_SUITE_TKIP,
140#ifdef FEATURE_WLAN_CCX
141#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
142 WLAN_CIPHER_SUITE_KRK,
143 WLAN_CIPHER_SUITE_CCMP,
144#else
145 WLAN_CIPHER_SUITE_CCMP,
146#endif
147#ifdef FEATURE_WLAN_WAPI
148 WLAN_CIPHER_SUITE_SMS4,
149#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700150#ifdef WLAN_FEATURE_11W
151 WLAN_CIPHER_SUITE_AES_CMAC,
152#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700153};
154
155static inline int is_broadcast_ether_addr(const u8 *addr)
156{
157 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
158 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
159}
160
161static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530162{
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 HDD2GHZCHAN(2412, 1, 0) ,
164 HDD2GHZCHAN(2417, 2, 0) ,
165 HDD2GHZCHAN(2422, 3, 0) ,
166 HDD2GHZCHAN(2427, 4, 0) ,
167 HDD2GHZCHAN(2432, 5, 0) ,
168 HDD2GHZCHAN(2437, 6, 0) ,
169 HDD2GHZCHAN(2442, 7, 0) ,
170 HDD2GHZCHAN(2447, 8, 0) ,
171 HDD2GHZCHAN(2452, 9, 0) ,
172 HDD2GHZCHAN(2457, 10, 0) ,
173 HDD2GHZCHAN(2462, 11, 0) ,
174 HDD2GHZCHAN(2467, 12, 0) ,
175 HDD2GHZCHAN(2472, 13, 0) ,
176 HDD2GHZCHAN(2484, 14, 0) ,
177};
178
Jeff Johnson295189b2012-06-20 16:38:30 -0700179static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
180{
181 HDD2GHZCHAN(2412, 1, 0) ,
182 HDD2GHZCHAN(2437, 6, 0) ,
183 HDD2GHZCHAN(2462, 11, 0) ,
184};
Jeff Johnson295189b2012-06-20 16:38:30 -0700185
186static struct ieee80211_channel hdd_channels_5_GHZ[] =
187{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700188 HDD5GHZCHAN(4920, 240, 0) ,
189 HDD5GHZCHAN(4940, 244, 0) ,
190 HDD5GHZCHAN(4960, 248, 0) ,
191 HDD5GHZCHAN(4980, 252, 0) ,
192 HDD5GHZCHAN(5040, 208, 0) ,
193 HDD5GHZCHAN(5060, 212, 0) ,
194 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 HDD5GHZCHAN(5180, 36, 0) ,
196 HDD5GHZCHAN(5200, 40, 0) ,
197 HDD5GHZCHAN(5220, 44, 0) ,
198 HDD5GHZCHAN(5240, 48, 0) ,
199 HDD5GHZCHAN(5260, 52, 0) ,
200 HDD5GHZCHAN(5280, 56, 0) ,
201 HDD5GHZCHAN(5300, 60, 0) ,
202 HDD5GHZCHAN(5320, 64, 0) ,
203 HDD5GHZCHAN(5500,100, 0) ,
204 HDD5GHZCHAN(5520,104, 0) ,
205 HDD5GHZCHAN(5540,108, 0) ,
206 HDD5GHZCHAN(5560,112, 0) ,
207 HDD5GHZCHAN(5580,116, 0) ,
208 HDD5GHZCHAN(5600,120, 0) ,
209 HDD5GHZCHAN(5620,124, 0) ,
210 HDD5GHZCHAN(5640,128, 0) ,
211 HDD5GHZCHAN(5660,132, 0) ,
212 HDD5GHZCHAN(5680,136, 0) ,
213 HDD5GHZCHAN(5700,140, 0) ,
214 HDD5GHZCHAN(5745,149, 0) ,
215 HDD5GHZCHAN(5765,153, 0) ,
216 HDD5GHZCHAN(5785,157, 0) ,
217 HDD5GHZCHAN(5805,161, 0) ,
218 HDD5GHZCHAN(5825,165, 0) ,
219};
220
221static struct ieee80211_rate g_mode_rates[] =
222{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530223 HDD_G_MODE_RATETAB(10, 0x1, 0),
224 HDD_G_MODE_RATETAB(20, 0x2, 0),
225 HDD_G_MODE_RATETAB(55, 0x4, 0),
226 HDD_G_MODE_RATETAB(110, 0x8, 0),
227 HDD_G_MODE_RATETAB(60, 0x10, 0),
228 HDD_G_MODE_RATETAB(90, 0x20, 0),
229 HDD_G_MODE_RATETAB(120, 0x40, 0),
230 HDD_G_MODE_RATETAB(180, 0x80, 0),
231 HDD_G_MODE_RATETAB(240, 0x100, 0),
232 HDD_G_MODE_RATETAB(360, 0x200, 0),
233 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530235};
Jeff Johnson295189b2012-06-20 16:38:30 -0700236
237static struct ieee80211_rate a_mode_rates[] =
238{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530239 HDD_G_MODE_RATETAB(60, 0x10, 0),
240 HDD_G_MODE_RATETAB(90, 0x20, 0),
241 HDD_G_MODE_RATETAB(120, 0x40, 0),
242 HDD_G_MODE_RATETAB(180, 0x80, 0),
243 HDD_G_MODE_RATETAB(240, 0x100, 0),
244 HDD_G_MODE_RATETAB(360, 0x200, 0),
245 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700246 HDD_G_MODE_RATETAB(540, 0x800, 0),
247};
248
249static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
250{
251 .channels = hdd_channels_2_4_GHZ,
252 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
253 .band = IEEE80211_BAND_2GHZ,
254 .bitrates = g_mode_rates,
255 .n_bitrates = g_mode_rates_size,
256 .ht_cap.ht_supported = 1,
257 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
258 | IEEE80211_HT_CAP_GRN_FLD
259 | IEEE80211_HT_CAP_DSSSCCK40
260 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
261 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
262 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
263 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
264 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
265 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
266};
267
Jeff Johnson295189b2012-06-20 16:38:30 -0700268static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
269{
270 .channels = hdd_social_channels_2_4_GHZ,
271 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
272 .band = IEEE80211_BAND_2GHZ,
273 .bitrates = g_mode_rates,
274 .n_bitrates = g_mode_rates_size,
275 .ht_cap.ht_supported = 1,
276 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
277 | IEEE80211_HT_CAP_GRN_FLD
278 | IEEE80211_HT_CAP_DSSSCCK40
279 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
280 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
281 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
282 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
283 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
284 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
285};
Jeff Johnson295189b2012-06-20 16:38:30 -0700286
287static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
288{
289 .channels = hdd_channels_5_GHZ,
290 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
291 .band = IEEE80211_BAND_5GHZ,
292 .bitrates = a_mode_rates,
293 .n_bitrates = a_mode_rates_size,
294 .ht_cap.ht_supported = 1,
295 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
296 | IEEE80211_HT_CAP_GRN_FLD
297 | IEEE80211_HT_CAP_DSSSCCK40
298 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
299 | IEEE80211_HT_CAP_SGI_40
300 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
301 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
302 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
303 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
304 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
305 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
306};
307
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530308/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 TX/RX direction for each kind of interface */
310static const struct ieee80211_txrx_stypes
311wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
312 [NL80211_IFTYPE_STATION] = {
313 .tx = 0xffff,
314 .rx = BIT(SIR_MAC_MGMT_ACTION) |
315 BIT(SIR_MAC_MGMT_PROBE_REQ),
316 },
317 [NL80211_IFTYPE_AP] = {
318 .tx = 0xffff,
319 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
320 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
321 BIT(SIR_MAC_MGMT_PROBE_REQ) |
322 BIT(SIR_MAC_MGMT_DISASSOC) |
323 BIT(SIR_MAC_MGMT_AUTH) |
324 BIT(SIR_MAC_MGMT_DEAUTH) |
325 BIT(SIR_MAC_MGMT_ACTION),
326 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700327 [NL80211_IFTYPE_ADHOC] = {
328 .tx = 0xffff,
329 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
330 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
331 BIT(SIR_MAC_MGMT_PROBE_REQ) |
332 BIT(SIR_MAC_MGMT_DISASSOC) |
333 BIT(SIR_MAC_MGMT_AUTH) |
334 BIT(SIR_MAC_MGMT_DEAUTH) |
335 BIT(SIR_MAC_MGMT_ACTION),
336 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 [NL80211_IFTYPE_P2P_CLIENT] = {
338 .tx = 0xffff,
339 .rx = BIT(SIR_MAC_MGMT_ACTION) |
340 BIT(SIR_MAC_MGMT_PROBE_REQ),
341 },
342 [NL80211_IFTYPE_P2P_GO] = {
343 /* This is also same as for SoftAP */
344 .tx = 0xffff,
345 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
346 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
347 BIT(SIR_MAC_MGMT_PROBE_REQ) |
348 BIT(SIR_MAC_MGMT_DISASSOC) |
349 BIT(SIR_MAC_MGMT_AUTH) |
350 BIT(SIR_MAC_MGMT_DEAUTH) |
351 BIT(SIR_MAC_MGMT_ACTION),
352 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700353};
354
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800356static const struct ieee80211_iface_limit
357wlan_hdd_iface_limit[] = {
358 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800359 /* max = 3 ; Our driver create two interfaces during driver init
360 * wlan0 and p2p0 interfaces. p2p0 is considered as station
361 * interface until a group is formed. In JB architecture, once the
362 * group is formed, interface type of p2p0 is changed to P2P GO or
363 * Client.
364 * When supplicant remove the group, it first issue a set interface
365 * cmd to change the mode back to Station. In JB this works fine as
366 * we advertize two station type interface during driver init.
367 * Some vendors create separate interface for P2P GO/Client,
368 * after group formation(Third one). But while group remove
369 * supplicant first tries to change the mode(3rd interface) to STATION
370 * But as we advertized only two sta type interfaces nl80211 was
371 * returning error for the third one which was leading to failure in
372 * delete interface. Ideally while removing the group, supplicant
373 * should not try to change the 3rd interface mode to Station type.
374 * Till we get a fix in wpa_supplicant, we advertize max STA
375 * interface type to 3
376 */
377 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800378 .types = BIT(NL80211_IFTYPE_STATION),
379 },
380 {
381 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700382 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383 },
384 {
385 .max = 1,
386 .types = BIT(NL80211_IFTYPE_P2P_GO) |
387 BIT(NL80211_IFTYPE_P2P_CLIENT),
388 },
389};
390
391/* By default, only single channel concurrency is allowed */
392static struct ieee80211_iface_combination
393wlan_hdd_iface_combination = {
394 .limits = wlan_hdd_iface_limit,
395 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800396 /*
397 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
398 * and p2p0 interfaces during driver init
399 * Some vendors create separate interface for P2P operations.
400 * wlan0: STA interface
401 * p2p0: P2P Device interface, action frames goes
402 * through this interface.
403 * p2p-xx: P2P interface, After GO negotiation this interface is
404 * created for p2p operations(GO/CLIENT interface).
405 */
406 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
408 .beacon_int_infra_match = false,
409};
410#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411
Jeff Johnson295189b2012-06-20 16:38:30 -0700412static struct cfg80211_ops wlan_hdd_cfg80211_ops;
413
414/* Data rate 100KBPS based on IE Index */
415struct index_data_rate_type
416{
417 v_U8_t beacon_rate_index;
418 v_U16_t supported_rate[4];
419};
420
421/* 11B, 11G Rate table include Basic rate and Extended rate
422 The IDX field is the rate index
423 The HI field is the rate when RSSI is strong or being ignored
424 (in this case we report actual rate)
425 The MID field is the rate when RSSI is moderate
426 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
427 The LO field is the rate when RSSI is low
428 (in this case we don't report rates, actual current rate used)
429 */
430static const struct
431{
432 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700433 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700434} supported_data_rate[] =
435{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700436/* IDX HI HM LM LO (RSSI-based index */
437 {2, { 10, 10, 10, 0}},
438 {4, { 20, 20, 10, 0}},
439 {11, { 55, 20, 10, 0}},
440 {12, { 60, 55, 20, 0}},
441 {18, { 90, 55, 20, 0}},
442 {22, {110, 55, 20, 0}},
443 {24, {120, 90, 60, 0}},
444 {36, {180, 120, 60, 0}},
445 {44, {220, 180, 60, 0}},
446 {48, {240, 180, 90, 0}},
447 {66, {330, 180, 90, 0}},
448 {72, {360, 240, 90, 0}},
449 {96, {480, 240, 120, 0}},
450 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700451};
452
453/* MCS Based rate table */
454static struct index_data_rate_type supported_mcs_rate[] =
455{
456/* MCS L20 L40 S20 S40 */
457 {0, {65, 135, 72, 150}},
458 {1, {130, 270, 144, 300}},
459 {2, {195, 405, 217, 450}},
460 {3, {260, 540, 289, 600}},
461 {4, {390, 810, 433, 900}},
462 {5, {520, 1080, 578, 1200}},
463 {6, {585, 1215, 650, 1350}},
464 {7, {650, 1350, 722, 1500}}
465};
466
Leo Chang6f8870f2013-03-26 18:11:36 -0700467#ifdef WLAN_FEATURE_11AC
468
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530469#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700470
471struct index_vht_data_rate_type
472{
473 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530474 v_U16_t supported_VHT80_rate[2];
475 v_U16_t supported_VHT40_rate[2];
476 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700477};
478
479typedef enum
480{
481 DATA_RATE_11AC_MAX_MCS_7,
482 DATA_RATE_11AC_MAX_MCS_8,
483 DATA_RATE_11AC_MAX_MCS_9,
484 DATA_RATE_11AC_MAX_MCS_NA
485} eDataRate11ACMaxMcs;
486
487/* MCS Based VHT rate table */
488static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
489{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530490/* MCS L80 S80 L40 S40 L20 S40*/
491 {0, {293, 325}, {135, 150}, {65, 72}},
492 {1, {585, 650}, {270, 300}, {130, 144}},
493 {2, {878, 975}, {405, 450}, {195, 217}},
494 {3, {1170, 1300}, {540, 600}, {260, 289}},
495 {4, {1755, 1950}, {810, 900}, {390, 433}},
496 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
497 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
498 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
499 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
500 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700501};
502#endif /* WLAN_FEATURE_11AC */
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504extern struct net_device_ops net_ops_struct;
505
Leo Chang9056f462013-08-01 19:21:11 -0700506#ifdef WLAN_NL80211_TESTMODE
507enum wlan_hdd_tm_attr
508{
509 WLAN_HDD_TM_ATTR_INVALID = 0,
510 WLAN_HDD_TM_ATTR_CMD = 1,
511 WLAN_HDD_TM_ATTR_DATA = 2,
512 WLAN_HDD_TM_ATTR_TYPE = 3,
513 /* keep last */
514 WLAN_HDD_TM_ATTR_AFTER_LAST,
515 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
516};
517
518enum wlan_hdd_tm_cmd
519{
520 WLAN_HDD_TM_CMD_WLAN_HB = 1,
521};
522
523#define WLAN_HDD_TM_DATA_MAX_LEN 5000
524
525static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
526{
527 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
528 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
529 .len = WLAN_HDD_TM_DATA_MAX_LEN },
530};
531#endif /* WLAN_NL80211_TESTMODE */
532
Jeff Johnson295189b2012-06-20 16:38:30 -0700533/*
534 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530535 * This function is called by hdd_wlan_startup()
536 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700537 * This function is used to initialize and register wiphy structure.
538 */
539struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
540{
541 struct wiphy *wiphy;
542 ENTER();
543
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530544 /*
545 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700546 */
547 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
548
549 if (!wiphy)
550 {
551 /* Print error and jump into err label and free the memory */
552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
553 return NULL;
554 }
555
556 return wiphy;
557}
558
559/*
560 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530561 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 * private ioctl to change the band value
563 */
564int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
565{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530566 int i, j;
567 eNVChannelEnabledType channelEnabledState;
568
Jeff Johnsone7245742012-09-05 17:12:55 -0700569 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530570 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700571 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530572
573 if (NULL == wiphy->bands[i])
574 {
575 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
576 __func__, i);
577 continue;
578 }
579
580 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
581 {
582 struct ieee80211_supported_band *band = wiphy->bands[i];
583
584 channelEnabledState = vos_nv_getChannelEnabledState(
585 band->channels[j].hw_value);
586
587 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
588 {
589 // Enable Social channels for P2P
590 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
591 NV_CHANNEL_ENABLE == channelEnabledState)
592 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
593 else
594 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
595 continue;
596 }
597 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
598 {
599 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
600 continue;
601 }
602
603 if (NV_CHANNEL_DISABLE == channelEnabledState ||
604 NV_CHANNEL_INVALID == channelEnabledState)
605 {
606 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
607 }
608 else if (NV_CHANNEL_DFS == channelEnabledState)
609 {
610 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
611 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
612 }
613 else
614 {
615 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
616 |IEEE80211_CHAN_RADAR);
617 }
618 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700619 }
620 return 0;
621}
622/*
623 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530624 * This function is called by hdd_wlan_startup()
625 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700626 * This function is used to initialize and register wiphy structure.
627 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530628int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700629 struct wiphy *wiphy,
630 hdd_config_t *pCfg
631 )
632{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530633
634 int i, j;
635
Jeff Johnsone7245742012-09-05 17:12:55 -0700636 ENTER();
637
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 /* Now bind the underlying wlan device with wiphy */
639 set_wiphy_dev(wiphy, dev);
640
641 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
642
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700643 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700644
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700645#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700646 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
647 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
648 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700649 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700650#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700651#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
652 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800653#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700654 || pCfg->isFastRoamIniFeatureEnabled
655#endif
656#ifdef FEATURE_WLAN_CCX
657 || pCfg->isCcxIniFeatureEnabled
658#endif
659 )
660 {
661 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
662 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800663#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800664#ifdef FEATURE_WLAN_TDLS
665 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
666 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
667#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530668#ifdef FEATURE_WLAN_SCAN_PNO
669 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
670 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
671 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
672#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800673
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700674 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
675 driver can still register regulatory callback and
676 it will get CRDA setting in wiphy->band[], but
677 driver need to determine what to do with both
678 regulatory settings */
679 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700680
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530681 wiphy->max_scan_ssids = MAX_SCAN_SSID;
682
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530683 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700684
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530685 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
686
Jeff Johnson295189b2012-06-20 16:38:30 -0700687 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530688 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700690 | BIT(NL80211_IFTYPE_P2P_CLIENT)
691 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 | BIT(NL80211_IFTYPE_AP);
693
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800695 if( pCfg->enableMCC )
696 {
697 /* Currently, supports up to two channels */
698 wlan_hdd_iface_combination.num_different_channels = 2;
699
700 if( !pCfg->allowMCCGODiffBI )
701 wlan_hdd_iface_combination.beacon_int_infra_match = true;
702
703 }
704 wiphy->iface_combinations = &wlan_hdd_iface_combination;
705 wiphy->n_iface_combinations = 1;
706#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800707
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 /* Before registering we need to update the ht capabilitied based
709 * on ini values*/
710 if( !pCfg->ShortGI20MhzEnable )
711 {
712 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
713 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
714 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
715 }
716
717 if( !pCfg->ShortGI40MhzEnable )
718 {
719 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
720 }
721
722 if( !pCfg->nChannelBondingMode5GHz )
723 {
724 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
725 }
726
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530727 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
728 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
729
730 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
731 {
732
733 if (NULL == wiphy->bands[i])
734 {
735 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
736 __func__, i);
737 continue;
738 }
739
740 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
741 {
742 struct ieee80211_supported_band *band = wiphy->bands[i];
743
744 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
745 {
746 // Enable social channels for P2P
747 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
748 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
749 else
750 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
751 continue;
752 }
753 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
754 {
755 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
756 continue;
757 }
758 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 }
760 /*Initialise the supported cipher suite details*/
761 wiphy->cipher_suites = hdd_cipher_suites;
762 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
763
764 /*signal strength in mBm (100*dBm) */
765 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
766
767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700768 wiphy->max_remain_on_channel_duration = 1000;
769#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700770
771 /* Register our wiphy dev with cfg80211 */
772 if (0 > wiphy_register(wiphy))
773 {
774 /* print eror */
775 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
776 return -EIO;
777 }
778
779 EXIT();
780 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530781}
Jeff Johnson295189b2012-06-20 16:38:30 -0700782
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700783/* In this function we will try to get default country code from crda.
784 If the gCrdaDefaultCountryCode is configured in ini file,
785 we will try to call user space crda to get the regulatory settings for
786 that country. We will timeout if we can't get it from crda.
787 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
788*/
789int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
790{
791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530792 int status;
793
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700794 if (memcmp(pCfg->crdaDefaultCountryCode,
795 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
796 {
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530797 INIT_COMPLETION(pHddCtx->driver_crda_req);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700798 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
Madan Mohan Koyyalamudi113ac742013-08-06 22:45:43 +0530799 status = wait_for_completion_interruptible_timeout(
800 &pHddCtx->driver_crda_req,
801 msecs_to_jiffies(CRDA_WAIT_TIME));
802 if (!status)
803 {
804 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: timeout waiting for CRDA REQ",
805 __func__);
806 }
807
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700808 /* if the country is not found from current regulatory.bin,
809 fall back to world domain */
810 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
811 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700812 }
813 return 0;
814}
815
Jeff Johnson295189b2012-06-20 16:38:30 -0700816/* In this function we will do all post VOS start initialization.
817 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530818 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700819*/
820void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
821{
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
823 /* Register for all P2P action, public action etc frames */
824 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
825
Jeff Johnsone7245742012-09-05 17:12:55 -0700826 ENTER();
827
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 /* Right now we are registering these frame when driver is getting
829 initialized. Once we will move to 2.6.37 kernel, in which we have
830 frame register ops, we will move this code as a part of that */
831 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530832 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700833 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
834
835 /* GAS Initial Response */
836 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
837 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530838
Jeff Johnson295189b2012-06-20 16:38:30 -0700839 /* GAS Comeback Request */
840 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
841 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
842
843 /* GAS Comeback Response */
844 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
845 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
846
847 /* P2P Public Action */
848 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530849 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 P2P_PUBLIC_ACTION_FRAME_SIZE );
851
852 /* P2P Action */
853 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
854 (v_U8_t*)P2P_ACTION_FRAME,
855 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700856
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530857 /* WNM BSS Transition Request frame */
858 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
859 (v_U8_t*)WNM_BSS_ACTION_FRAME,
860 WNM_BSS_ACTION_FRAME_SIZE );
861
Chet Lanctot186b5732013-03-18 10:26:30 -0700862#ifdef WLAN_FEATURE_11W
863 /* SA Query Response Action Frame */
864 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
865 (v_U8_t*)SA_QUERY_FRAME_RSP,
866 SA_QUERY_FRAME_RSP_SIZE );
867#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700868}
869
870void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
871{
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
873 /* Register for all P2P action, public action etc frames */
874 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
875
Jeff Johnsone7245742012-09-05 17:12:55 -0700876 ENTER();
877
Jeff Johnson295189b2012-06-20 16:38:30 -0700878 /* Right now we are registering these frame when driver is getting
879 initialized. Once we will move to 2.6.37 kernel, in which we have
880 frame register ops, we will move this code as a part of that */
881 /* GAS Initial Request */
882
883 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
884 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
885
886 /* GAS Initial Response */
887 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
888 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530889
Jeff Johnson295189b2012-06-20 16:38:30 -0700890 /* GAS Comeback Request */
891 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
892 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
893
894 /* GAS Comeback Response */
895 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
896 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
897
898 /* P2P Public Action */
899 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530900 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 P2P_PUBLIC_ACTION_FRAME_SIZE );
902
903 /* P2P Action */
904 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
905 (v_U8_t*)P2P_ACTION_FRAME,
906 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700907
908#ifdef WLAN_FEATURE_11W
909 /* SA Query Response Action Frame */
910 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
911 (v_U8_t*)SA_QUERY_FRAME_RSP,
912 SA_QUERY_FRAME_RSP_SIZE );
913#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700914}
915
916#ifdef FEATURE_WLAN_WAPI
917void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
918 const u8 *mac_addr, u8 *key , int key_Len)
919{
920 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
921 tCsrRoamSetKey setKey;
922 v_BOOL_t isConnected = TRUE;
923 int status = 0;
924 v_U32_t roamId= 0xFF;
925 tANI_U8 *pKeyPtr = NULL;
926 int n = 0;
927
928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
929 __func__,pAdapter->device_mode);
930
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530931 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 setKey.keyId = key_index; // Store Key ID
933 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
934 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
935 setKey.paeRole = 0 ; // the PAE role
936 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
937 {
938 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
939 }
940 else
941 {
942 isConnected = hdd_connIsConnected(pHddStaCtx);
943 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
944 }
945 setKey.keyLength = key_Len;
946 pKeyPtr = setKey.Key;
947 memcpy( pKeyPtr, key, key_Len);
948
949 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
950 __func__, key_Len);
951 for (n = 0 ; n < key_Len; n++)
952 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
953 __func__,n,setKey.Key[n]);
954
955 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
956 if ( isConnected )
957 {
958 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
959 pAdapter->sessionId, &setKey, &roamId );
960 }
961 if ( status != 0 )
962 {
963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
964 "[%4d] sme_RoamSetKey returned ERROR status= %d",
965 __LINE__, status );
966 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
967 }
968}
969#endif /* FEATURE_WLAN_WAPI*/
970
971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530972int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 beacon_data_t **ppBeacon,
974 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700975#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530976int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700977 beacon_data_t **ppBeacon,
978 struct cfg80211_beacon_data *params,
979 int dtim_period)
980#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530981{
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 int size;
983 beacon_data_t *beacon = NULL;
984 beacon_data_t *old = NULL;
985 int head_len,tail_len;
986
Jeff Johnsone7245742012-09-05 17:12:55 -0700987 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700988 if (params->head && !params->head_len)
989 return -EINVAL;
990
991 old = pAdapter->sessionCtx.ap.beacon;
992
993 if (!params->head && !old)
994 return -EINVAL;
995
996 if (params->tail && !params->tail_len)
997 return -EINVAL;
998
999#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1000 /* Kernel 3.0 is not updating dtim_period for set beacon */
1001 if (!params->dtim_period)
1002 return -EINVAL;
1003#endif
1004
1005 if(params->head)
1006 head_len = params->head_len;
1007 else
1008 head_len = old->head_len;
1009
1010 if(params->tail || !old)
1011 tail_len = params->tail_len;
1012 else
1013 tail_len = old->tail_len;
1014
1015 size = sizeof(beacon_data_t) + head_len + tail_len;
1016
1017 beacon = kzalloc(size, GFP_KERNEL);
1018
1019 if( beacon == NULL )
1020 return -ENOMEM;
1021
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001022#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 if(params->dtim_period || !old )
1024 beacon->dtim_period = params->dtim_period;
1025 else
1026 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001027#else
1028 if(dtim_period || !old )
1029 beacon->dtim_period = dtim_period;
1030 else
1031 beacon->dtim_period = old->dtim_period;
1032#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301033
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1035 beacon->tail = beacon->head + head_len;
1036 beacon->head_len = head_len;
1037 beacon->tail_len = tail_len;
1038
1039 if(params->head) {
1040 memcpy (beacon->head,params->head,beacon->head_len);
1041 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301042 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001043 if(old)
1044 memcpy (beacon->head,old->head,beacon->head_len);
1045 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301046
Jeff Johnson295189b2012-06-20 16:38:30 -07001047 if(params->tail) {
1048 memcpy (beacon->tail,params->tail,beacon->tail_len);
1049 }
1050 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301051 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 memcpy (beacon->tail,old->tail,beacon->tail_len);
1053 }
1054
1055 *ppBeacon = beacon;
1056
1057 kfree(old);
1058
1059 return 0;
1060
1061}
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
1063v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1064{
1065 int left = length;
1066 v_U8_t *ptr = pIes;
1067 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301068
Jeff Johnson295189b2012-06-20 16:38:30 -07001069 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301070 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001071 elem_id = ptr[0];
1072 elem_len = ptr[1];
1073 left -= 2;
1074 if(elem_len > left)
1075 {
1076 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001077 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 eid,elem_len,left);
1079 return NULL;
1080 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301081 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 {
1083 return ptr;
1084 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301085
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 left -= elem_len;
1087 ptr += (elem_len + 2);
1088 }
1089 return NULL;
1090}
1091
Jeff Johnson295189b2012-06-20 16:38:30 -07001092/* Check if rate is 11g rate or not */
1093static int wlan_hdd_rate_is_11g(u8 rate)
1094{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001095 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 u8 i;
1097 for (i = 0; i < 8; i++)
1098 {
1099 if(rate == gRateArray[i])
1100 return TRUE;
1101 }
1102 return FALSE;
1103}
1104
1105/* Check for 11g rate and set proper 11g only mode */
1106static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1107 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1108{
1109 u8 i, num_rates = pIe[0];
1110
1111 pIe += 1;
1112 for ( i = 0; i < num_rates; i++)
1113 {
1114 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1115 {
1116 /* If rate set have 11g rate than change the mode to 11G */
1117 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1118 if (pIe[i] & BASIC_RATE_MASK)
1119 {
1120 /* If we have 11g rate as basic rate, it means mode
1121 is 11g only mode.
1122 */
1123 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1124 *pCheckRatesfor11g = FALSE;
1125 }
1126 }
1127 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1128 {
1129 *require_ht = TRUE;
1130 }
1131 }
1132 return;
1133}
1134
1135static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1136{
1137 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1138 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1139 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1140 u8 checkRatesfor11g = TRUE;
1141 u8 require_ht = FALSE;
1142 u8 *pIe=NULL;
1143
1144 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1145
1146 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1147 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1148 if (pIe != NULL)
1149 {
1150 pIe += 1;
1151 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1152 &pConfig->SapHw_mode);
1153 }
1154
1155 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1156 WLAN_EID_EXT_SUPP_RATES);
1157 if (pIe != NULL)
1158 {
1159
1160 pIe += 1;
1161 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1162 &pConfig->SapHw_mode);
1163 }
1164
1165 if( pConfig->channel > 14 )
1166 {
1167 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1168 }
1169
1170 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1171 WLAN_EID_HT_CAPABILITY);
1172
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301173 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001174 {
1175 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1176 if(require_ht)
1177 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1178 }
1179}
1180
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301181static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1182 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1183{
1184 v_U8_t ielen = 0;
1185 v_U8_t *pIe = NULL;
1186 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1187
1188 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1189 pBeacon->tail, pBeacon->tail_len);
1190
1191 if (pIe)
1192 {
1193 ielen = pIe[1] + 2;
1194 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1195 {
1196 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1197 }
1198 else
1199 {
1200 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1201 return -EINVAL;
1202 }
1203 *total_ielen += ielen;
1204 }
1205 return 0;
1206}
1207
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001208#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001209static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1210 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001211#else
1212static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1213 struct cfg80211_beacon_data *params)
1214#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001215{
1216 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301217 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001219 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001220
1221 genie = vos_mem_malloc(MAX_GENIE_LEN);
1222
1223 if(genie == NULL) {
1224
1225 return -ENOMEM;
1226 }
1227
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301228 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1229 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001230 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301231 ret = -EINVAL;
1232 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001233 }
1234
1235#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301236 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1237 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1238 {
1239 ret = -EINVAL;
1240 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 }
1242#endif
1243
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301244 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1245 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001246 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301247 ret = -EINVAL;
1248 goto done;
1249 }
1250
1251 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1252 {
1253 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1254 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301256 ret = -EINVAL;
1257 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001258 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001260
1261 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1262 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1263 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1264 {
1265 hddLog(LOGE,
1266 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001267 ret = -EINVAL;
1268 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001269 }
1270
1271 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1272 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1273 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1274 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1275 ==eHAL_STATUS_FAILURE)
1276 {
1277 hddLog(LOGE,
1278 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001279 ret = -EINVAL;
1280 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001281 }
1282
1283 // Added for ProResp IE
1284 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1285 {
1286 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1287 u8 probe_rsp_ie_len[3] = {0};
1288 u8 counter = 0;
1289 /* Check Probe Resp Length if it is greater then 255 then Store
1290 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1291 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1292 Store More then 255 bytes into One Variable.
1293 */
1294 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1295 {
1296 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1297 {
1298 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1299 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1300 }
1301 else
1302 {
1303 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1304 rem_probe_resp_ie_len = 0;
1305 }
1306 }
1307
1308 rem_probe_resp_ie_len = 0;
1309
1310 if (probe_rsp_ie_len[0] > 0)
1311 {
1312 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1313 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1314 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1315 probe_rsp_ie_len[0], NULL,
1316 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1317 {
1318 hddLog(LOGE,
1319 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001320 ret = -EINVAL;
1321 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001322 }
1323 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1324 }
1325
1326 if (probe_rsp_ie_len[1] > 0)
1327 {
1328 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1329 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1330 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1331 probe_rsp_ie_len[1], NULL,
1332 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1333 {
1334 hddLog(LOGE,
1335 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001336 ret = -EINVAL;
1337 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 }
1339 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1340 }
1341
1342 if (probe_rsp_ie_len[2] > 0)
1343 {
1344 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1345 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1346 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1347 probe_rsp_ie_len[2], NULL,
1348 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1349 {
1350 hddLog(LOGE,
1351 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001352 ret = -EINVAL;
1353 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001354 }
1355 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1356 }
1357
1358 if (probe_rsp_ie_len[1] == 0 )
1359 {
1360 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1361 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1362 eANI_BOOLEAN_FALSE) )
1363 {
1364 hddLog(LOGE,
1365 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1366 }
1367 }
1368
1369 if (probe_rsp_ie_len[2] == 0 )
1370 {
1371 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1372 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1373 eANI_BOOLEAN_FALSE) )
1374 {
1375 hddLog(LOGE,
1376 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1377 }
1378 }
1379
1380 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1381 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1382 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1383 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1384 == eHAL_STATUS_FAILURE)
1385 {
1386 hddLog(LOGE,
1387 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001388 ret = -EINVAL;
1389 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 }
1391 }
1392 else
1393 {
1394 // Reset WNI_CFG_PROBE_RSP Flags
1395 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1396
1397 hddLog(VOS_TRACE_LEVEL_INFO,
1398 "%s: No Probe Response IE received in set beacon",
1399 __func__);
1400 }
1401
1402 // Added for AssocResp IE
1403 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1404 {
1405 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1406 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1407 params->assocresp_ies_len, NULL,
1408 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1409 {
1410 hddLog(LOGE,
1411 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001412 ret = -EINVAL;
1413 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001414 }
1415
1416 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1417 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1418 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1419 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1420 == eHAL_STATUS_FAILURE)
1421 {
1422 hddLog(LOGE,
1423 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001424 ret = -EINVAL;
1425 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 }
1427 }
1428 else
1429 {
1430 hddLog(VOS_TRACE_LEVEL_INFO,
1431 "%s: No Assoc Response IE received in set beacon",
1432 __func__);
1433
1434 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1435 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1436 eANI_BOOLEAN_FALSE) )
1437 {
1438 hddLog(LOGE,
1439 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1440 }
1441 }
1442
Jeff Johnsone7245742012-09-05 17:12:55 -07001443done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001444 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301445 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001446}
Jeff Johnson295189b2012-06-20 16:38:30 -07001447
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301448/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 * FUNCTION: wlan_hdd_validate_operation_channel
1450 * called by wlan_hdd_cfg80211_start_bss() and
1451 * wlan_hdd_cfg80211_set_channel()
1452 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301453 * channel list.
1454 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001455VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001456{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301457
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 v_U32_t num_ch = 0;
1459 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1460 u32 indx = 0;
1461 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301462 v_U8_t fValidChannel = FALSE, count = 0;
1463 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301464
Jeff Johnson295189b2012-06-20 16:38:30 -07001465 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1466
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301467 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301469 /* Validate the channel */
1470 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001471 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301472 if ( channel == rfChannels[count].channelNum )
1473 {
1474 fValidChannel = TRUE;
1475 break;
1476 }
1477 }
1478 if (fValidChannel != TRUE)
1479 {
1480 hddLog(VOS_TRACE_LEVEL_ERROR,
1481 "%s: Invalid Channel [%d]", __func__, channel);
1482 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001483 }
1484 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301485 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301487 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1488 valid_ch, &num_ch))
1489 {
1490 hddLog(VOS_TRACE_LEVEL_ERROR,
1491 "%s: failed to get valid channel list", __func__);
1492 return VOS_STATUS_E_FAILURE;
1493 }
1494 for (indx = 0; indx < num_ch; indx++)
1495 {
1496 if (channel == valid_ch[indx])
1497 {
1498 break;
1499 }
1500 }
1501
1502 if (indx >= num_ch)
1503 {
1504 hddLog(VOS_TRACE_LEVEL_ERROR,
1505 "%s: Invalid Channel [%d]", __func__, channel);
1506 return VOS_STATUS_E_FAILURE;
1507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001508 }
1509 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301510
Jeff Johnson295189b2012-06-20 16:38:30 -07001511}
1512
Viral Modi3a32cc52013-02-08 11:14:52 -08001513/**
1514 * FUNCTION: wlan_hdd_cfg80211_set_channel
1515 * This function is used to set the channel number
1516 */
1517static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1518 struct ieee80211_channel *chan,
1519 enum nl80211_channel_type channel_type
1520 )
1521{
1522 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001523 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001524 hdd_adapter_t *pAdapter = NULL;
1525 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301526 hdd_context_t *pHddCtx;
1527 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001528
1529 ENTER();
1530
1531 if( NULL == dev )
1532 {
1533 hddLog(VOS_TRACE_LEVEL_ERROR,
1534 "%s: Called with dev = NULL.\n", __func__);
1535 return -ENODEV;
1536 }
1537 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1538
1539 hddLog(VOS_TRACE_LEVEL_INFO,
1540 "%s: device_mode = %d freq = %d \n",__func__,
1541 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301542
1543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1544 status = wlan_hdd_validate_context(pHddCtx);
1545
1546 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001547 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1549 "%s: HDD context is not valid", __func__);
1550 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001551 }
1552
1553 /*
1554 * Do freq to chan conversion
1555 * TODO: for 11a
1556 */
1557
1558 channel = ieee80211_frequency_to_channel(freq);
1559
1560 /* Check freq range */
1561 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1562 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1563 {
1564 hddLog(VOS_TRACE_LEVEL_ERROR,
1565 "%s: Channel [%d] is outside valid range from %d to %d\n",
1566 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1567 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1568 return -EINVAL;
1569 }
1570
1571 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1572
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301573 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1574 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001575 {
1576 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1577 {
1578 hddLog(VOS_TRACE_LEVEL_ERROR,
1579 "%s: Invalid Channel [%d] \n", __func__, channel);
1580 return -EINVAL;
1581 }
1582 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1583 "%s: set channel to [%d] for device mode =%d",
1584 __func__, channel,pAdapter->device_mode);
1585 }
1586 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001587 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001588 )
1589 {
1590 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1591 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1592 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1593
1594 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1595 {
1596 /* Link is up then return cant set channel*/
1597 hddLog( VOS_TRACE_LEVEL_ERROR,
1598 "%s: IBSS Associated, can't set the channel\n", __func__);
1599 return -EINVAL;
1600 }
1601
1602 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1603 pHddStaCtx->conn_info.operationChannel = channel;
1604 pRoamProfile->ChannelInfo.ChannelList =
1605 &pHddStaCtx->conn_info.operationChannel;
1606 }
1607 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001608 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001609 )
1610 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301611 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1612 {
1613 if(VOS_STATUS_SUCCESS !=
1614 wlan_hdd_validate_operation_channel(pAdapter,channel))
1615 {
1616 hddLog(VOS_TRACE_LEVEL_ERROR,
1617 "%s: Invalid Channel [%d] \n", __func__, channel);
1618 return -EINVAL;
1619 }
1620 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1621 }
1622 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001623 {
1624 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1625
1626 /* If auto channel selection is configured as enable/ 1 then ignore
1627 channel set by supplicant
1628 */
1629 if ( cfg_param->apAutoChannelSelection )
1630 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301631 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1632 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001633 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1634 "%s: set channel to auto channel (0) for device mode =%d",
1635 __func__, pAdapter->device_mode);
1636 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301637 else
1638 {
1639 if(VOS_STATUS_SUCCESS !=
1640 wlan_hdd_validate_operation_channel(pAdapter,channel))
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 "%s: Invalid Channel [%d] \n", __func__, channel);
1644 return -EINVAL;
1645 }
1646 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1647 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001648 }
1649 }
1650 else
1651 {
1652 hddLog(VOS_TRACE_LEVEL_FATAL,
1653 "%s: Invalid device mode failed to set valid channel", __func__);
1654 return -EINVAL;
1655 }
1656 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301657 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001658}
1659
Jeff Johnson295189b2012-06-20 16:38:30 -07001660#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1661static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1662 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001663#else
1664static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1665 struct cfg80211_beacon_data *params,
1666 const u8 *ssid, size_t ssid_len,
1667 enum nl80211_hidden_ssid hidden_ssid)
1668#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001669{
1670 tsap_Config_t *pConfig;
1671 beacon_data_t *pBeacon = NULL;
1672 struct ieee80211_mgmt *pMgmt_frame;
1673 v_U8_t *pIe=NULL;
1674 v_U16_t capab_info;
1675 eCsrAuthType RSNAuthType;
1676 eCsrEncryptionType RSNEncryptType;
1677 eCsrEncryptionType mcRSNEncryptType;
1678 int status = VOS_STATUS_SUCCESS;
1679 tpWLAN_SAPEventCB pSapEventCallback;
1680 hdd_hostapd_state_t *pHostapdState;
1681 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1682 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301683 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001684 struct qc_mac_acl_entry *acl_entry = NULL;
1685 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001686 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001687
1688 ENTER();
1689
1690 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1691
1692 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1693
1694 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1695
1696 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1697
1698 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1699
1700 //channel is already set in the set_channel Call back
1701 //pConfig->channel = pCommitConfig->channel;
1702
1703 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301704 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001705 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1706
1707 pConfig->dtim_period = pBeacon->dtim_period;
1708
1709 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1710 pConfig->dtim_period);
1711
1712
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001713 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001714 {
1715 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001717 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001719 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001720 pConfig->ieee80211d = 1;
1721 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1722 sme_setRegInfo(hHal, pConfig->countryCode);
1723 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001725 else
1726 {
1727 pConfig->ieee80211d = 0;
1728 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301729 /*
1730 * If auto channel is configured i.e. channel is 0,
1731 * so skip channel validation.
1732 */
1733 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1734 {
1735 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1736 {
1737 hddLog(VOS_TRACE_LEVEL_ERROR,
1738 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1739 return -EINVAL;
1740 }
1741 }
1742 else
1743 {
1744 if(1 != pHddCtx->is_dynamic_channel_range_set)
1745 {
1746 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1747 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1748 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1749 }
1750 pHddCtx->is_dynamic_channel_range_set = 0;
1751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001752 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001753 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 {
1755 pConfig->ieee80211d = 0;
1756 }
1757 pConfig->authType = eSAP_AUTO_SWITCH;
1758
1759 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301760
1761 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001762 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1763
1764 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1765
1766 /*Set wps station to configured*/
1767 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1768
1769 if(pIe)
1770 {
1771 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1772 {
1773 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1774 return -EINVAL;
1775 }
1776 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1777 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001778 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001779 /* Check 15 bit of WPS IE as it contain information for wps state
1780 * WPS state
1781 */
1782 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1783 {
1784 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1785 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1786 {
1787 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1788 }
1789 }
1790 }
1791 else
1792 {
1793 pConfig->wps_state = SAP_WPS_DISABLED;
1794 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301795 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001796
1797 pConfig->RSNWPAReqIELength = 0;
1798 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301799 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001800 WLAN_EID_RSN);
1801 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301802 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1804 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1805 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301806 /* The actual processing may eventually be more extensive than
1807 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 * by the app.
1809 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301810 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001811 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1812 &RSNEncryptType,
1813 &mcRSNEncryptType,
1814 &RSNAuthType,
1815 pConfig->pRSNWPAReqIE[1]+2,
1816 pConfig->pRSNWPAReqIE );
1817
1818 if( VOS_STATUS_SUCCESS == status )
1819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301820 /* Now copy over all the security attributes you have
1821 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001822 * */
1823 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1824 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1825 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1826 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301827 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001828 "EncryptionType = %d mcEncryptionType = %d\n"),
1829 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1830 }
1831 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301832
Jeff Johnson295189b2012-06-20 16:38:30 -07001833 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1834 pBeacon->tail, pBeacon->tail_len);
1835
1836 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1837 {
1838 if (pConfig->pRSNWPAReqIE)
1839 {
1840 /*Mixed mode WPA/WPA2*/
1841 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1842 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1843 }
1844 else
1845 {
1846 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1847 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1848 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301849 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1851 &RSNEncryptType,
1852 &mcRSNEncryptType,
1853 &RSNAuthType,
1854 pConfig->pRSNWPAReqIE[1]+2,
1855 pConfig->pRSNWPAReqIE );
1856
1857 if( VOS_STATUS_SUCCESS == status )
1858 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301859 /* Now copy over all the security attributes you have
1860 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 * */
1862 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1863 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1864 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1865 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301866 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001867 "EncryptionType = %d mcEncryptionType = %d\n"),
1868 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1869 }
1870 }
1871 }
1872
Jeff Johnson4416a782013-03-25 14:17:50 -07001873 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1874 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1875 return -EINVAL;
1876 }
1877
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1879
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001881 if (params->ssid != NULL)
1882 {
1883 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1884 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1885 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1886 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1887 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001888#else
1889 if (ssid != NULL)
1890 {
1891 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1892 pConfig->SSIDinfo.ssid.length = ssid_len;
1893 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1894 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1895 }
1896#endif
1897
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301898 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301900
Jeff Johnson295189b2012-06-20 16:38:30 -07001901 /* default value */
1902 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1903 pConfig->num_accept_mac = 0;
1904 pConfig->num_deny_mac = 0;
1905
1906 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1907 pBeacon->tail, pBeacon->tail_len);
1908
1909 /* pIe for black list is following form:
1910 type : 1 byte
1911 length : 1 byte
1912 OUI : 4 bytes
1913 acl type : 1 byte
1914 no of mac addr in black list: 1 byte
1915 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301916 */
1917 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001918 {
1919 pConfig->SapMacaddr_acl = pIe[6];
1920 pConfig->num_deny_mac = pIe[7];
1921 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1922 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301923 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
1924 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001925 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1926 for (i = 0; i < pConfig->num_deny_mac; i++)
1927 {
1928 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1929 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001931 }
1932 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1933 pBeacon->tail, pBeacon->tail_len);
1934
1935 /* pIe for white list is following form:
1936 type : 1 byte
1937 length : 1 byte
1938 OUI : 4 bytes
1939 acl type : 1 byte
1940 no of mac addr in white list: 1 byte
1941 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301942 */
1943 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001944 {
1945 pConfig->SapMacaddr_acl = pIe[6];
1946 pConfig->num_accept_mac = pIe[7];
1947 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1948 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301949 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
1950 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1952 for (i = 0; i < pConfig->num_accept_mac; i++)
1953 {
1954 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1955 acl_entry++;
1956 }
1957 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05301958
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1960
Jeff Johnsone7245742012-09-05 17:12:55 -07001961#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001962 /* Overwrite the hostapd setting for HW mode only for 11ac.
1963 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1964 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1965 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1966 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301967 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001968 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1969 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001970 {
1971 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07001972
1973 /* Disable VHT support in 2.4 GHz band */
1974 if (pConfig->channel <= 14 &&
1975 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
1976 {
1977 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
1978 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001979 }
1980#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301981
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001982 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1983 {
1984 sme_SelectCBMode(hHal,
1985 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1986 pConfig->channel);
1987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001988 // ht_capab is not what the name conveys,this is used for protection bitmap
1989 pConfig->ht_capab =
1990 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1991
1992 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1993 {
1994 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1995 return -EINVAL;
1996 }
1997
1998 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301999 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2001 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302002 pConfig->obssProtEnabled =
2003 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002004
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302007 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002008 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
2009 (int)pConfig->channel);
2010 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302011 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
2012 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07002013 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302014 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
2016 pConfig->protEnabled, pConfig->obssProtEnabled);
2017
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302018 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 {
2020 //Bss already started. just return.
2021 //TODO Probably it should update some beacon params.
2022 hddLog( LOGE, "Bss Already started...Ignore the request");
2023 EXIT();
2024 return 0;
2025 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302026
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 pConfig->persona = pHostapdAdapter->device_mode;
2028
2029 pSapEventCallback = hdd_hostapd_SAPEventCB;
2030 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2031 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2032 {
2033 hddLog(LOGE,FL("SAP Start Bss fail\n"));
2034 return -EINVAL;
2035 }
2036
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302037 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2039
2040 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302041
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302043 {
2044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 ("ERROR: HDD vos wait for single_event failed!!\n"));
2046 VOS_ASSERT(0);
2047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302048
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 //Succesfully started Bss update the state bit.
2050 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2051
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002052#ifdef WLAN_FEATURE_P2P_DEBUG
2053 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2054 {
2055 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2056 {
2057 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2058 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002059 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002060 }
2061 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2062 {
2063 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2064 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002065 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002066 }
2067 }
2068#endif
2069
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 pHostapdState->bCommit = TRUE;
2071 EXIT();
2072
2073 return 0;
2074}
2075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002076#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302077static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2078 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002079 struct beacon_parameters *params)
2080{
2081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302082 hdd_context_t *pHddCtx;
2083 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002084
2085 ENTER();
2086
2087 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2088
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2090 status = wlan_hdd_validate_context(pHddCtx);
2091
2092 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2095 "%s: HDD context is not valid", __func__);
2096 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002097 }
2098
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302099 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002100 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 )
2102 {
2103 beacon_data_t *old,*new;
2104
2105 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302106
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 if (old)
2108 return -EALREADY;
2109
2110 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2111
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 {
2114 hddLog(VOS_TRACE_LEVEL_FATAL,
2115 "%s:Error!!! Allocating the new beacon\n",__func__);
2116 return -EINVAL;
2117 }
2118
2119 pAdapter->sessionCtx.ap.beacon = new;
2120
2121 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2122 }
2123
2124 EXIT();
2125 return status;
2126}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302127
2128static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 struct net_device *dev,
2130 struct beacon_parameters *params)
2131{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302133 hdd_context_t *pHddCtx;
2134 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002135
2136 ENTER();
2137
2138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2139 __func__,pAdapter->device_mode);
2140
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2142 status = wlan_hdd_validate_context(pHddCtx);
2143
2144 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002145 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2147 "%s: HDD context is not valid", __func__);
2148 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002149 }
2150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302151 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302153 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002154 {
2155 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302156
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302158
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 if (!old)
2160 return -ENOENT;
2161
2162 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2163
2164 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302165 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002166 "%s: Error!!! Allocating the new beacon\n",__func__);
2167 return -EINVAL;
2168 }
2169
2170 pAdapter->sessionCtx.ap.beacon = new;
2171
2172 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2173 }
2174
2175 EXIT();
2176 return status;
2177}
2178
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002179#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2180
2181#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002182static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2183 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002184#else
2185static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2186 struct net_device *dev)
2187#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002188{
2189 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002190 hdd_context_t *pHddCtx = NULL;
2191 hdd_scaninfo_t *pScanInfo = NULL;
2192 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302193 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002194
2195 ENTER();
2196
2197 if (NULL == pAdapter)
2198 {
2199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002200 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 return -ENODEV;
2202 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002203
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302204 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2205 status = wlan_hdd_validate_context(pHddCtx);
2206
2207 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002208 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2210 "%s: HDD context is not valid", __func__);
2211 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002212 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002213
2214 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2215 if (NULL == staAdapter)
2216 {
2217 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2218 if (NULL == staAdapter)
2219 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002221 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002222 return -ENODEV;
2223 }
2224 }
2225
2226 pScanInfo = &pHddCtx->scan_info;
2227
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2229 __func__,pAdapter->device_mode);
2230
Jeff Johnsone7245742012-09-05 17:12:55 -07002231 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2232 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002233 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002234 hdd_abort_mac_scan(staAdapter->pHddCtx);
2235 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002236 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002237 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2238 if (!status)
2239 {
2240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002241 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002242 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002243 VOS_ASSERT(pScanInfo->mScanPending);
2244 return 0;
2245 }
2246 }
2247
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 )
2251 {
2252 beacon_data_t *old;
2253
2254 old = pAdapter->sessionCtx.ap.beacon;
2255
2256 if (!old)
2257 return -ENOENT;
2258
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260
2261 mutex_lock(&pHddCtx->sap_lock);
2262 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2263 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002264 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002265 {
2266 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2267
2268 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2269
2270 if (!VOS_IS_STATUS_SUCCESS(status))
2271 {
2272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2273 ("ERROR: HDD vos wait for single_event failed!!\n"));
2274 VOS_ASSERT(0);
2275 }
2276 }
2277 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2278 }
2279 mutex_unlock(&pHddCtx->sap_lock);
2280
2281 if(status != VOS_STATUS_SUCCESS)
2282 {
2283 hddLog(VOS_TRACE_LEVEL_FATAL,
2284 "%s:Error!!! Stopping the BSS\n",__func__);
2285 return -EINVAL;
2286 }
2287
Jeff Johnson4416a782013-03-25 14:17:50 -07002288 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2290 ==eHAL_STATUS_FAILURE)
2291 {
2292 hddLog(LOGE,
2293 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2294 }
2295
Jeff Johnson4416a782013-03-25 14:17:50 -07002296 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002297 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2298 eANI_BOOLEAN_FALSE) )
2299 {
2300 hddLog(LOGE,
2301 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2302 }
2303
2304 // Reset WNI_CFG_PROBE_RSP Flags
2305 wlan_hdd_reset_prob_rspies(pAdapter);
2306
2307 pAdapter->sessionCtx.ap.beacon = NULL;
2308 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002309#ifdef WLAN_FEATURE_P2P_DEBUG
2310 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2311 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2312 {
2313 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2314 "GO got removed");
2315 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2316 }
2317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002318 }
2319 EXIT();
2320 return status;
2321}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002322
2323#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2324
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302325static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2326 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327 struct cfg80211_ap_settings *params)
2328{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302329 hdd_adapter_t *pAdapter;
2330 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302331 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002332
2333 ENTER();
2334
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302335 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302338 "%s: Device is Null", __func__);
2339 return -ENODEV;
2340 }
2341
2342 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2343 if (NULL == pAdapter)
2344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302346 "%s: HDD adapter is Null", __func__);
2347 return -ENODEV;
2348 }
2349
2350 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2351 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302353 "%s: HDD adapter magic is invalid", __func__);
2354 return -ENODEV;
2355 }
2356
2357 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302358 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302359
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302360 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302361 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2363 "%s: HDD context is not valid", __func__);
2364 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302365 }
2366
2367 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2368 __func__, pAdapter->device_mode);
2369
2370 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002371 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002372 )
2373 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302374 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002375
2376 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302377
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002378 if (old)
2379 return -EALREADY;
2380
2381 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2382
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302383 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002384 {
2385 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302386 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002387 return -EINVAL;
2388 }
2389 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002390#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2391 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2392#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002393 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2394 params->ssid_len, params->hidden_ssid);
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05302395 if (0 == status)
2396 {
2397 hdd_start_p2p_go_connection_in_progress_timer(pAdapter);
2398 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002399 }
2400
2401 EXIT();
2402 return status;
2403}
2404
2405
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302406static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002407 struct net_device *dev,
2408 struct cfg80211_beacon_data *params)
2409{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302411 hdd_context_t *pHddCtx;
2412 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002413
2414 ENTER();
2415
2416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2417 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302418
2419 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2420 status = wlan_hdd_validate_context(pHddCtx);
2421
2422 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002423 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2425 "%s: HDD context is not valid", __func__);
2426 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002427 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002428
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302429 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002430 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302431 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002432 {
2433 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302434
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002435 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002437 if (!old)
2438 return -ENOENT;
2439
2440 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2441
2442 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302443 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002444 "%s: Error!!! Allocating the new beacon\n",__func__);
2445 return -EINVAL;
2446 }
2447
2448 pAdapter->sessionCtx.ap.beacon = new;
2449
2450 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2451 }
2452
2453 EXIT();
2454 return status;
2455}
2456
2457#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2458
Jeff Johnson295189b2012-06-20 16:38:30 -07002459
2460static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2461 struct net_device *dev,
2462 struct bss_parameters *params)
2463{
2464 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2465
2466 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302467
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2469 __func__,pAdapter->device_mode);
2470
2471 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002472 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302473 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002474 {
2475 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2476 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302477 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002478 {
2479 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002481 }
2482
2483 EXIT();
2484 return 0;
2485}
2486
2487/*
2488 * FUNCTION: wlan_hdd_cfg80211_change_iface
2489 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2490 */
2491int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2492 struct net_device *ndev,
2493 enum nl80211_iftype type,
2494 u32 *flags,
2495 struct vif_params *params
2496 )
2497{
2498 struct wireless_dev *wdev;
2499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2500 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002501 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 tCsrRoamProfile *pRoamProfile = NULL;
2503 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302504 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002505 eMib_dot11DesiredBssType connectedBssType;
2506 VOS_STATUS status;
2507
2508 ENTER();
2509
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302510 status = wlan_hdd_validate_context(pHddCtx);
2511
2512 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2515 "%s: HDD context is not valid", __func__);
2516 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 }
2518
2519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2520 __func__, pAdapter->device_mode);
2521
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302522 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 wdev = ndev->ieee80211_ptr;
2524
2525#ifdef WLAN_BTAMP_FEATURE
2526 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2527 (NL80211_IFTYPE_ADHOC == type)||
2528 (NL80211_IFTYPE_AP == type)||
2529 (NL80211_IFTYPE_P2P_GO == type))
2530 {
2531 pHddCtx->isAmpAllowed = VOS_FALSE;
2532 // stop AMP traffic
2533 status = WLANBAP_StopAmp();
2534 if(VOS_STATUS_SUCCESS != status )
2535 {
2536 pHddCtx->isAmpAllowed = VOS_TRUE;
2537 hddLog(VOS_TRACE_LEVEL_FATAL,
2538 "%s: Failed to stop AMP", __func__);
2539 return -EINVAL;
2540 }
2541 }
2542#endif //WLAN_BTAMP_FEATURE
2543 /* Reset the current device mode bit mask*/
2544 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2545
2546 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002548 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 )
2550 {
2551 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2552 pRoamProfile = &pWextState->roamProfile;
2553 LastBSSType = pRoamProfile->BSSType;
2554
2555 switch (type)
2556 {
2557 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002559 hddLog(VOS_TRACE_LEVEL_INFO,
2560 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2561 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002562#ifdef WLAN_FEATURE_11AC
2563 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2564 {
2565 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2566 }
2567#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302568 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002569 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002570 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002571 //Check for sub-string p2p to confirm its a p2p interface
2572 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302573 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002574 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2575 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2576 }
2577 else
2578 {
2579 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002580 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002581 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302582#ifdef FEATURE_WLAN_TDLS
2583 /* The open adapter for the p2p shall skip initializations in
2584 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2585 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2586 * tdls_init when the change_iface sets the device mode to
2587 * WLAN_HDD_P2P_CLIENT.
2588 */
2589
2590 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2591 {
2592 if (0 != wlan_hdd_tdls_init (pAdapter))
2593 {
2594 return -EINVAL;
2595 }
2596 }
2597#endif
2598
Jeff Johnson295189b2012-06-20 16:38:30 -07002599 break;
2600 case NL80211_IFTYPE_ADHOC:
2601 hddLog(VOS_TRACE_LEVEL_INFO,
2602 "%s: setting interface Type to ADHOC", __func__);
2603 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2604 pRoamProfile->phyMode =
2605 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002606 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 wdev->iftype = type;
2608 break;
2609
2610 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002611 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002612 {
2613 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2614 "%s: setting interface Type to %s", __func__,
2615 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2616
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002617 //Cancel any remain on channel for GO mode
2618 if (NL80211_IFTYPE_P2P_GO == type)
2619 {
2620 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2621 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002622 if (NL80211_IFTYPE_AP == type)
2623 {
2624 /* As Loading WLAN Driver one interface being created for p2p device
2625 * address. This will take one HW STA and the max number of clients
2626 * that can connect to softAP will be reduced by one. so while changing
2627 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2628 * interface as it is not required in SoftAP mode.
2629 */
2630
2631 // Get P2P Adapter
2632 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2633
2634 if (pP2pAdapter)
2635 {
2636 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2637 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2638 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2639 }
2640 }
2641
Jeff Johnson295189b2012-06-20 16:38:30 -07002642 //De-init the adapter.
2643 hdd_stop_adapter( pHddCtx, pAdapter );
2644 hdd_deinit_adapter( pHddCtx, pAdapter );
2645 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2647 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002648
2649 //Disable BMPS and IMPS if enabled
2650 //before starting Go
2651 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2652 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302653 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002654 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2655 {
2656 //Fail to Exit BMPS
2657 VOS_ASSERT(0);
2658 }
2659 }
2660
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002661 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2662 (pConfig->apRandomBssidEnabled))
2663 {
2664 /* To meet Android requirements create a randomized
2665 MAC address of the form 02:1A:11:Fx:xx:xx */
2666 get_random_bytes(&ndev->dev_addr[3], 3);
2667 ndev->dev_addr[0] = 0x02;
2668 ndev->dev_addr[1] = 0x1A;
2669 ndev->dev_addr[2] = 0x11;
2670 ndev->dev_addr[3] |= 0xF0;
2671 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2672 VOS_MAC_ADDR_SIZE);
2673 pr_info("wlan: Generated HotSpot BSSID "
2674 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2675 ndev->dev_addr[0],
2676 ndev->dev_addr[1],
2677 ndev->dev_addr[2],
2678 ndev->dev_addr[3],
2679 ndev->dev_addr[4],
2680 ndev->dev_addr[5]);
2681 }
2682
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 hdd_set_ap_ops( pAdapter->dev );
2684
2685 status = hdd_init_ap_mode(pAdapter);
2686 if(status != VOS_STATUS_SUCCESS)
2687 {
2688 hddLog(VOS_TRACE_LEVEL_FATAL,
2689 "%s: Error initializing the ap mode", __func__);
2690 return -EINVAL;
2691 }
2692 hdd_set_conparam(1);
2693
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 /*interface type changed update in wiphy structure*/
2695 if(wdev)
2696 {
2697 wdev->iftype = type;
2698 pHddCtx->change_iface = type;
2699 }
2700 else
2701 {
2702 hddLog(VOS_TRACE_LEVEL_ERROR,
2703 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2704 return -EINVAL;
2705 }
2706 goto done;
2707 }
2708
2709 default:
2710 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2711 __func__);
2712 return -EOPNOTSUPP;
2713 }
2714 }
2715 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002716 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002717 )
2718 {
2719 switch(type)
2720 {
2721 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002722 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002723 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002724 hdd_stop_adapter( pHddCtx, pAdapter );
2725 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002726 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002727 //Check for sub-string p2p to confirm its a p2p interface
2728 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002729 {
2730 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2731 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2732 }
2733 else
2734 {
2735 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002736 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002738 hdd_set_conparam(0);
2739 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002740 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2741 hdd_set_station_ops( pAdapter->dev );
2742 status = hdd_init_station_mode( pAdapter );
2743 if( VOS_STATUS_SUCCESS != status )
2744 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002745 /* In case of JB, for P2P-GO, only change interface will be called,
2746 * This is the right place to enable back bmps_imps()
2747 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05302748 if (pHddCtx->hdd_wlan_suspended)
2749 {
2750 hdd_set_pwrparams(pHddCtx);
2751 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002752 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 goto done;
2754 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002755 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002757 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2758 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002759 goto done;
2760 default:
2761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2762 __func__);
2763 return -EOPNOTSUPP;
2764
2765 }
2766
2767 }
2768 else
2769 {
2770 return -EOPNOTSUPP;
2771 }
2772
2773
2774 if(pRoamProfile)
2775 {
2776 if ( LastBSSType != pRoamProfile->BSSType )
2777 {
2778 /*interface type changed update in wiphy structure*/
2779 wdev->iftype = type;
2780
2781 /*the BSS mode changed, We need to issue disconnect
2782 if connected or in IBSS disconnect state*/
2783 if ( hdd_connGetConnectedBssType(
2784 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2785 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2786 {
2787 /*need to issue a disconnect to CSR.*/
2788 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2789 if( eHAL_STATUS_SUCCESS ==
2790 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2791 pAdapter->sessionId,
2792 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2793 {
2794 wait_for_completion_interruptible_timeout(
2795 &pAdapter->disconnect_comp_var,
2796 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2797 }
2798 }
2799 }
2800 }
2801
2802done:
2803 /*set bitmask based on updated value*/
2804 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07002805
2806 /* Only STA mode support TM now
2807 * all other mode, TM feature should be disabled */
2808 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
2809 (~VOS_STA & pHddCtx->concurrency_mode) )
2810 {
2811 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
2812 }
2813
Jeff Johnson295189b2012-06-20 16:38:30 -07002814#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302815 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002816 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2817 {
2818 //we are ok to do AMP
2819 pHddCtx->isAmpAllowed = VOS_TRUE;
2820 }
2821#endif //WLAN_BTAMP_FEATURE
2822 EXIT();
2823 return 0;
2824}
2825
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002826#ifdef FEATURE_WLAN_TDLS
2827static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2828 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2829{
2830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2831 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2832 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002833 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002834
2835 ENTER();
2836
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302837 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002838 {
2839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "Invalid arguments");
2841 return -EINVAL;
2842 }
Hoonki Lee27511902013-03-14 18:19:06 -07002843
2844 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2845 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2846 {
2847 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2848 "%s: TDLS mode is disabled OR not enabled in FW."
2849 MAC_ADDRESS_STR " Request declined.",
2850 __func__, MAC_ADDR_ARRAY(mac));
2851 return -ENOTSUPP;
2852 }
2853
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002854 if (pHddCtx->isLogpInProgress)
2855 {
2856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2857 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002858 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002859 return -EBUSY;
2860 }
2861
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002862 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2863
2864 if ( NULL == pTdlsPeer ) {
2865 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2867 __func__, MAC_ADDR_ARRAY(mac), update);
2868 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002869 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002870
2871 /* in add station, we accept existing valid staId if there is */
2872 if ((0 == update) &&
2873 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2874 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002875 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002876 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002877 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002878 " link_status %d. staId %d. add station ignored.",
2879 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2880 return 0;
2881 }
2882 /* in change station, we accept only when staId is valid */
2883 if ((1 == update) &&
2884 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2885 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2888 "%s: " MAC_ADDRESS_STR
2889 " link status %d. staId %d. change station %s.",
2890 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2891 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2892 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002893 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002894
2895 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002896 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002897 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "%s: " MAC_ADDRESS_STR
2900 " TDLS setup is ongoing. Request declined.",
2901 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002902 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002903 }
2904
2905 /* first to check if we reached to maximum supported TDLS peer.
2906 TODO: for now, return -EPERM looks working fine,
2907 but need to check if any other errno fit into this category.*/
2908 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2909 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2911 "%s: " MAC_ADDRESS_STR
2912 " TDLS Max peer already connected. Request declined.",
2913 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002914 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002915 }
2916 else
2917 {
2918 hddTdlsPeer_t *pTdlsPeer;
2919 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002920 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002921 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2923 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2924 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002925 return -EPERM;
2926 }
2927 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002928 if (0 == update)
2929 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002930
Jeff Johnsond75fe012013-04-06 10:53:06 -07002931 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302932 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002933 {
2934 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2935 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002936 if(StaParams->htcap_present)
2937 {
2938 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2939 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2940 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2941 "ht_capa->extended_capabilities: %0x",
2942 StaParams->HTCap.extendedHtCapInfo);
2943 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002944 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2945 "params->capability: %0x",StaParams->capability);
2946 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2947 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002948 if(StaParams->vhtcap_present)
2949 {
2950 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2951 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2952 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2953 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2954 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002955 {
2956 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002958 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2959 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2960 "[%d]: %x ", i, StaParams->supported_rates[i]);
2961 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002962 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302963 else if ((1 == update) && (NULL == StaParams))
2964 {
2965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2966 "%s : update is true, but staParams is NULL. Error!", __func__);
2967 return -EPERM;
2968 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002969
2970 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2971
2972 if (!update)
2973 {
2974 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2975 pAdapter->sessionId, mac);
2976 }
2977 else
2978 {
2979 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2980 pAdapter->sessionId, mac, StaParams);
2981 }
2982
2983 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2984 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2985
2986 if (!status)
2987 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002989 "%s: timeout waiting for tdls add station indication",
2990 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002991 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002992 }
2993 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2994 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002996 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002997 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002998 }
2999
3000 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003001
3002error:
3003 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3004 return -EPERM;
3005
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003006}
3007#endif
3008
Jeff Johnson295189b2012-06-20 16:38:30 -07003009static int wlan_hdd_change_station(struct wiphy *wiphy,
3010 struct net_device *dev,
3011 u8 *mac,
3012 struct station_parameters *params)
3013{
3014 VOS_STATUS status = VOS_STATUS_SUCCESS;
3015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303016 hdd_context_t *pHddCtx;
3017 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003018 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003019#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003020 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003021 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003022#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003023 ENTER();
3024
Gopichand Nakkala29149562013-05-10 21:43:41 +05303025 if ((NULL == pAdapter))
3026 {
3027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3028 "invalid adapter ");
3029 return -EINVAL;
3030 }
3031
3032 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3033 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3034
3035 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3036 {
3037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3038 "invalid HDD state or HDD station context");
3039 return -EINVAL;
3040 }
3041
3042 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003043 {
3044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3045 "%s:LOGP in Progress. Ignore!!!", __func__);
3046 return -EAGAIN;
3047 }
3048
Jeff Johnson295189b2012-06-20 16:38:30 -07003049 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3050
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003051 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3052 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003053 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003054 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303056 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003057 WLANTL_STA_AUTHENTICATED);
3058
Gopichand Nakkala29149562013-05-10 21:43:41 +05303059 if (status != VOS_STATUS_SUCCESS)
3060 {
3061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3062 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3063 return -EINVAL;
3064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003065 }
3066 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003067 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3068 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303069#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003070 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3071 StaParams.capability = params->capability;
3072 StaParams.uapsd_queues = params->uapsd_queues;
3073 StaParams.max_sp = params->max_sp;
3074
3075 if (0 != params->ext_capab_len)
3076 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3077 sizeof(StaParams.extn_capability));
3078
3079 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003080 {
3081 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003082 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003083 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003084
3085 StaParams.supported_rates_len = params->supported_rates_len;
3086
3087 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3088 * The supported_rates array , for all the structures propogating till Add Sta
3089 * to the firmware has to be modified , if the supplicant (ieee80211) is
3090 * modified to send more rates.
3091 */
3092
3093 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3094 */
3095 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3096 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3097
3098 if (0 != StaParams.supported_rates_len) {
3099 int i = 0;
3100 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3101 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003103 "Supported Rates with Length %d", StaParams.supported_rates_len);
3104 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003106 "[%d]: %0x", i, StaParams.supported_rates[i]);
3107 }
3108
3109 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003110 {
3111 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003112 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003113 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003114
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003115 if (0 != params->ext_capab_len ) {
3116 /*Define A Macro : TODO Sunil*/
3117 if ((1<<4) & StaParams.extn_capability[3]) {
3118 isBufSta = 1;
3119 }
3120 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303121 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3122 params->max_sp, isBufSta);
3123 if (VOS_STATUS_SUCCESS != status) {
3124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3125 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3126 return -EINVAL;
3127 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003128 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3129
3130 if (VOS_STATUS_SUCCESS != status) {
3131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3132 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3133 return -EINVAL;
3134 }
3135 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003136#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303137 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003138 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003139 return status;
3140}
3141
3142/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003143 * FUNCTION: wlan_hdd_cfg80211_add_key
3144 * This function is used to initialize the key information
3145 */
3146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003147static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003148 struct net_device *ndev,
3149 u8 key_index, bool pairwise,
3150 const u8 *mac_addr,
3151 struct key_params *params
3152 )
3153#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003154static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 struct net_device *ndev,
3156 u8 key_index, const u8 *mac_addr,
3157 struct key_params *params
3158 )
3159#endif
3160{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003162 tCsrRoamSetKey setKey;
3163 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303164 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003165 v_U32_t roamId= 0xFF;
3166 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 hdd_hostapd_state_t *pHostapdState;
3168 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003169 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303170 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003171
3172 ENTER();
3173
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303174 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3175 status = wlan_hdd_validate_context(pHddCtx);
3176
3177 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003178 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3180 "%s: HDD context is not valid", __func__);
3181 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003182 }
3183
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3185 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187 if (CSR_MAX_NUM_KEY <= key_index)
3188 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003190 key_index);
3191
3192 return -EINVAL;
3193 }
3194
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003195 if (CSR_MAX_KEY_LEN < params->key_len)
3196 {
3197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3198 params->key_len);
3199
3200 return -EINVAL;
3201 }
3202
3203 hddLog(VOS_TRACE_LEVEL_INFO,
3204 "%s: called with key index = %d & key length %d",
3205 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003206
3207 /*extract key idx, key len and key*/
3208 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3209 setKey.keyId = key_index;
3210 setKey.keyLength = params->key_len;
3211 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3212
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003213 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 {
3215 case WLAN_CIPHER_SUITE_WEP40:
3216 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3217 break;
3218
3219 case WLAN_CIPHER_SUITE_WEP104:
3220 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3221 break;
3222
3223 case WLAN_CIPHER_SUITE_TKIP:
3224 {
3225 u8 *pKey = &setKey.Key[0];
3226 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3227
3228 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3229
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003230 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003231
3232 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003233 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003234 |--------------|----------|----------|
3235 <---16bytes---><--8bytes--><--8bytes-->
3236
3237 */
3238 /*Sme expects the 32 bytes key to be in the below order
3239
3240 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003241 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003242 |--------------|----------|----------|
3243 <---16bytes---><--8bytes--><--8bytes-->
3244 */
3245 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003246 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003247
3248 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003249 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003250
3251 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003252 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003253
3254
3255 break;
3256 }
3257
3258 case WLAN_CIPHER_SUITE_CCMP:
3259 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3260 break;
3261
3262#ifdef FEATURE_WLAN_WAPI
3263 case WLAN_CIPHER_SUITE_SMS4:
3264 {
3265 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3266 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3267 params->key, params->key_len);
3268 return 0;
3269 }
3270#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003271
Jeff Johnson295189b2012-06-20 16:38:30 -07003272#ifdef FEATURE_WLAN_CCX
3273 case WLAN_CIPHER_SUITE_KRK:
3274 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3275 break;
3276#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003277
3278#ifdef WLAN_FEATURE_11W
3279 case WLAN_CIPHER_SUITE_AES_CMAC:
3280 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003281 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003282#endif
3283
Jeff Johnson295189b2012-06-20 16:38:30 -07003284 default:
3285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3286 __func__, params->cipher);
3287 return -EOPNOTSUPP;
3288 }
3289
3290 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3291 __func__, setKey.encType);
3292
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003293 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3295 (!pairwise)
3296#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003297 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003298#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003299 )
3300 {
3301 /* set group key*/
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3303 "%s- %d: setting Broadcast key",
3304 __func__, __LINE__);
3305 setKey.keyDirection = eSIR_RX_ONLY;
3306 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3307 }
3308 else
3309 {
3310 /* set pairwise key*/
3311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3312 "%s- %d: setting pairwise key",
3313 __func__, __LINE__);
3314 setKey.keyDirection = eSIR_TX_RX;
3315 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3316 }
3317 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3318 {
3319 setKey.keyDirection = eSIR_TX_RX;
3320 /*Set the group key*/
3321 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3322 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003323
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003324 if ( 0 != status )
3325 {
3326 hddLog(VOS_TRACE_LEVEL_ERROR,
3327 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3328 return -EINVAL;
3329 }
3330 /*Save the keys here and call sme_RoamSetKey for setting
3331 the PTK after peer joins the IBSS network*/
3332 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3333 &setKey, sizeof(tCsrRoamSetKey));
3334 return status;
3335 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303336 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3337 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3338 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003339 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003340 if( pHostapdState->bssState == BSS_START )
3341 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003342 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3343
3344 if ( status != eHAL_STATUS_SUCCESS )
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3348 __LINE__, status );
3349 }
3350 }
3351
3352 /* Saving WEP keys */
3353 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3354 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3355 {
3356 //Save the wep key in ap context. Issue setkey after the BSS is started.
3357 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3358 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3359 }
3360 else
3361 {
3362 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003363 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003364 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3365 }
3366 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003367 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3368 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003369 {
3370 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3371 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3372
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303373#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3374 if (!pairwise)
3375#else
3376 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3377#endif
3378 {
3379 /* set group key*/
3380 if (pHddStaCtx->roam_info.deferKeyComplete)
3381 {
3382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3383 "%s- %d: Perform Set key Complete",
3384 __func__, __LINE__);
3385 hdd_PerformRoamSetKeyComplete(pAdapter);
3386 }
3387 }
3388
Jeff Johnson295189b2012-06-20 16:38:30 -07003389 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3390
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003391 pWextState->roamProfile.Keys.defaultIndex = key_index;
3392
3393
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003394 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 params->key, params->key_len);
3396
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303397
Jeff Johnson295189b2012-06-20 16:38:30 -07003398 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3399
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303400 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003401 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303402 __func__, setKey.peerMac[0], setKey.peerMac[1],
3403 setKey.peerMac[2], setKey.peerMac[3],
3404 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003405 setKey.keyDirection);
3406
3407 vos_status = wlan_hdd_check_ula_done(pAdapter);
3408
3409 if ( vos_status != VOS_STATUS_SUCCESS )
3410 {
3411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3412 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3413 __LINE__, vos_status );
3414
3415 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3416
3417 return -EINVAL;
3418
3419 }
3420
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003421#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303422 /* The supplicant may attempt to set the PTK once pre-authentication
3423 is done. Save the key in the UMAC and include it in the ADD BSS
3424 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003425 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303426 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003427 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303428 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3429 "%s: Update PreAuth Key success", __func__);
3430 return 0;
3431 }
3432 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3433 {
3434 hddLog(VOS_TRACE_LEVEL_ERROR,
3435 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303436 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003437 }
3438#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003439
3440 /* issue set key request to SME*/
3441 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3442 pAdapter->sessionId, &setKey, &roamId );
3443
3444 if ( 0 != status )
3445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303446 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003447 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3448 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3449 return -EINVAL;
3450 }
3451
3452
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303453 /* in case of IBSS as there was no information available about WEP keys during
3454 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303456 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3457 !( ( IW_AUTH_KEY_MGMT_802_1X
3458 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003459 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3460 )
3461 &&
3462 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3463 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3464 )
3465 )
3466 {
3467 setKey.keyDirection = eSIR_RX_ONLY;
3468 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3469
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303470 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303472 __func__, setKey.peerMac[0], setKey.peerMac[1],
3473 setKey.peerMac[2], setKey.peerMac[3],
3474 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003475 setKey.keyDirection);
3476
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303477 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003478 pAdapter->sessionId, &setKey, &roamId );
3479
3480 if ( 0 != status )
3481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303482 hddLog(VOS_TRACE_LEVEL_ERROR,
3483 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003484 __func__, status);
3485 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3486 return -EINVAL;
3487 }
3488 }
3489 }
3490
3491 return 0;
3492}
3493
3494/*
3495 * FUNCTION: wlan_hdd_cfg80211_get_key
3496 * This function is used to get the key information
3497 */
3498#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303499static int wlan_hdd_cfg80211_get_key(
3500 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003501 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303502 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003503 const u8 *mac_addr, void *cookie,
3504 void (*callback)(void *cookie, struct key_params*)
3505 )
3506#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303507static int wlan_hdd_cfg80211_get_key(
3508 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003509 struct net_device *ndev,
3510 u8 key_index, const u8 *mac_addr, void *cookie,
3511 void (*callback)(void *cookie, struct key_params*)
3512 )
3513#endif
3514{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3517 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3518 struct key_params params;
3519
3520 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303521
Jeff Johnson295189b2012-06-20 16:38:30 -07003522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3523 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 memset(&params, 0, sizeof(params));
3526
3527 if (CSR_MAX_NUM_KEY <= key_index)
3528 {
3529 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003531
3532 switch(pRoamProfile->EncryptionType.encryptionType[0])
3533 {
3534 case eCSR_ENCRYPT_TYPE_NONE:
3535 params.cipher = IW_AUTH_CIPHER_NONE;
3536 break;
3537
3538 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3539 case eCSR_ENCRYPT_TYPE_WEP40:
3540 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3541 break;
3542
3543 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3544 case eCSR_ENCRYPT_TYPE_WEP104:
3545 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3546 break;
3547
3548 case eCSR_ENCRYPT_TYPE_TKIP:
3549 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3550 break;
3551
3552 case eCSR_ENCRYPT_TYPE_AES:
3553 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3554 break;
3555
3556 default:
3557 params.cipher = IW_AUTH_CIPHER_NONE;
3558 break;
3559 }
3560
3561 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3562 params.seq_len = 0;
3563 params.seq = NULL;
3564 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3565 callback(cookie, &params);
3566 return 0;
3567}
3568
3569/*
3570 * FUNCTION: wlan_hdd_cfg80211_del_key
3571 * This function is used to delete the key information
3572 */
3573#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303574static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003575 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303576 u8 key_index,
3577 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003578 const u8 *mac_addr
3579 )
3580#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303581static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003582 struct net_device *ndev,
3583 u8 key_index,
3584 const u8 *mac_addr
3585 )
3586#endif
3587{
3588 int status = 0;
3589
3590 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303591 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003592 //it is observed that this is invalidating peer
3593 //key index whenever re-key is done. This is affecting data link.
3594 //It should be ok to ignore del_key.
3595#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303596 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3597 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003598 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3599 tCsrRoamSetKey setKey;
3600 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303601
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 ENTER();
3603
3604 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3605 __func__,pAdapter->device_mode);
3606
3607 if (CSR_MAX_NUM_KEY <= key_index)
3608 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 key_index);
3611
3612 return -EINVAL;
3613 }
3614
3615 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3616 setKey.keyId = key_index;
3617
3618 if (mac_addr)
3619 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3620 else
3621 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3622
3623 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3624
3625 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003626 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303627 )
3628 {
3629
3630 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003631 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3632 if( pHostapdState->bssState == BSS_START)
3633 {
3634 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303635
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 if ( status != eHAL_STATUS_SUCCESS )
3637 {
3638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3639 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3640 __LINE__, status );
3641 }
3642 }
3643 }
3644 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303645 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 )
3647 {
3648 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303650 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3651
3652 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003653 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303654 __func__, setKey.peerMac[0], setKey.peerMac[1],
3655 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003656 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303657 if(pAdapter->sessionCtx.station.conn_info.connState ==
3658 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303660 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003661 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303662
Jeff Johnson295189b2012-06-20 16:38:30 -07003663 if ( 0 != status )
3664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303665 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003666 "%s: sme_RoamSetKey failure, returned %d",
3667 __func__, status);
3668 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3669 return -EINVAL;
3670 }
3671 }
3672 }
3673#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003674 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 return status;
3676}
3677
3678/*
3679 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3680 * This function is used to set the default tx key index
3681 */
3682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3683static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3684 struct net_device *ndev,
3685 u8 key_index,
3686 bool unicast, bool multicast)
3687#else
3688static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3689 struct net_device *ndev,
3690 u8 key_index)
3691#endif
3692{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303693 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303694 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303695 hdd_wext_state_t *pWextState;
3696 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303697 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003698
3699 ENTER();
3700
Gopichand Nakkala29149562013-05-10 21:43:41 +05303701 if ((NULL == pAdapter))
3702 {
3703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3704 "invalid adapter");
3705 return -EINVAL;
3706 }
3707
3708 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3709 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3710
3711 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3712 {
3713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3714 "invalid Wext state or HDD context");
3715 return -EINVAL;
3716 }
3717
Jeff Johnson295189b2012-06-20 16:38:30 -07003718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3719 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303720
Jeff Johnson295189b2012-06-20 16:38:30 -07003721 if (CSR_MAX_NUM_KEY <= key_index)
3722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 key_index);
3725
3726 return -EINVAL;
3727 }
3728
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303729 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3730 status = wlan_hdd_validate_context(pHddCtx);
3731
3732 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003733 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3735 "%s: HDD context is not valid", __func__);
3736 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003737 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303738
Jeff Johnson295189b2012-06-20 16:38:30 -07003739 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303741 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003742 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303743 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003744 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303745 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003746 pWextState->roamProfile.EncryptionType.encryptionType[0])
3747 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303748 {
3749 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003750 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303751
Jeff Johnson295189b2012-06-20 16:38:30 -07003752 tCsrRoamSetKey setKey;
3753 v_U32_t roamId= 0xFF;
3754 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303755
3756 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003757 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303758
Jeff Johnson295189b2012-06-20 16:38:30 -07003759 Keys->defaultIndex = (u8)key_index;
3760 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3761 setKey.keyId = key_index;
3762 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303763
3764 vos_mem_copy(&setKey.Key[0],
3765 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303767
Gopichand Nakkala29149562013-05-10 21:43:41 +05303768 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303769
3770 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003771 &pHddStaCtx->conn_info.bssId[0],
3772 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303773
Gopichand Nakkala29149562013-05-10 21:43:41 +05303774 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3775 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3776 eCSR_ENCRYPT_TYPE_WEP104)
3777 {
3778 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3779 even though ap is configured for WEP-40 encryption. In this canse the key length
3780 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3781 type(104) and switching encryption type to 40*/
3782 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3783 eCSR_ENCRYPT_TYPE_WEP40;
3784 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3785 eCSR_ENCRYPT_TYPE_WEP40;
3786 }
3787
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303788 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003789 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303790
Jeff Johnson295189b2012-06-20 16:38:30 -07003791 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303792 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003793 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303794
Jeff Johnson295189b2012-06-20 16:38:30 -07003795 if ( 0 != status )
3796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303797 hddLog(VOS_TRACE_LEVEL_ERROR,
3798 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 status);
3800 return -EINVAL;
3801 }
3802 }
3803 }
3804
3805 /* In SoftAp mode setting key direction for default mode */
3806 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3807 {
3808 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3809 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3810 (eCSR_ENCRYPT_TYPE_AES !=
3811 pWextState->roamProfile.EncryptionType.encryptionType[0])
3812 )
3813 {
3814 /* Saving key direction for default key index to TX default */
3815 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3816 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3817 }
3818 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303819
Jeff Johnson295189b2012-06-20 16:38:30 -07003820 return status;
3821}
3822
Jeff Johnson295189b2012-06-20 16:38:30 -07003823/*
3824 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3825 * This function is used to inform the BSS details to nl80211 interface.
3826 */
3827static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3828 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3829{
3830 struct net_device *dev = pAdapter->dev;
3831 struct wireless_dev *wdev = dev->ieee80211_ptr;
3832 struct wiphy *wiphy = wdev->wiphy;
3833 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3834 int chan_no;
3835 int ie_length;
3836 const char *ie;
3837 unsigned int freq;
3838 struct ieee80211_channel *chan;
3839 int rssi = 0;
3840 struct cfg80211_bss *bss = NULL;
3841
3842 ENTER();
3843
3844 if( NULL == pBssDesc )
3845 {
3846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3847 return bss;
3848 }
3849
3850 chan_no = pBssDesc->channelId;
3851 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3852 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3853
3854 if( NULL == ie )
3855 {
3856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3857 return bss;
3858 }
3859
3860#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3861 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3862 {
3863 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3864 }
3865 else
3866 {
3867 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3868 }
3869#else
3870 freq = ieee80211_channel_to_frequency(chan_no);
3871#endif
3872
3873 chan = __ieee80211_get_channel(wiphy, freq);
3874
3875 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3876 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3877 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3878 if (bss == NULL)
3879 {
3880 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3881
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303882 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3883 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003884 pBssDesc->capabilityInfo,
3885 pBssDesc->beaconInterval, ie, ie_length,
3886 rssi, GFP_KERNEL ));
3887}
3888 else
3889 {
3890 return bss;
3891 }
3892}
3893
3894
3895
3896/*
3897 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3898 * This function is used to inform the BSS details to nl80211 interface.
3899 */
3900struct cfg80211_bss*
3901wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3902 tSirBssDescription *bss_desc
3903 )
3904{
3905 /*
3906 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3907 already exists in bss data base of cfg80211 for that particular BSS ID.
3908 Using cfg80211_inform_bss_frame to update the bss entry instead of
3909 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3910 now there is no possibility to get the mgmt(probe response) frame from PE,
3911 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3912 cfg80211_inform_bss_frame.
3913 */
3914 struct net_device *dev = pAdapter->dev;
3915 struct wireless_dev *wdev = dev->ieee80211_ptr;
3916 struct wiphy *wiphy = wdev->wiphy;
3917 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003918#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3919 qcom_ie_age *qie_age = NULL;
3920 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3921#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003922 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003924 const char *ie =
3925 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3926 unsigned int freq;
3927 struct ieee80211_channel *chan;
3928 struct ieee80211_mgmt *mgmt =
3929 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3930 struct cfg80211_bss *bss_status = NULL;
3931 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3932 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003933#ifdef WLAN_OPEN_SOURCE
3934 struct timespec ts;
3935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003936
3937 ENTER();
3938
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003939 if (!mgmt)
3940 return NULL;
3941
Jeff Johnson295189b2012-06-20 16:38:30 -07003942 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003943
3944#ifdef WLAN_OPEN_SOURCE
3945 /* Android does not want the timestamp from the frame.
3946 Instead it wants a monotonic increasing value */
3947 get_monotonic_boottime(&ts);
3948 mgmt->u.probe_resp.timestamp =
3949 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3950#else
3951 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003952 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3953 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003954
3955#endif
3956
Jeff Johnson295189b2012-06-20 16:38:30 -07003957 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3958 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003959
3960#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3961 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3962 /* Assuming this is the last IE, copy at the end */
3963 ie_length -=sizeof(qcom_ie_age);
3964 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3965 qie_age->element_id = QCOM_VENDOR_IE_ID;
3966 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3967 qie_age->oui_1 = QCOM_OUI1;
3968 qie_age->oui_2 = QCOM_OUI2;
3969 qie_age->oui_3 = QCOM_OUI3;
3970 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3971 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3972#endif
3973
Jeff Johnson295189b2012-06-20 16:38:30 -07003974 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303975 if (bss_desc->fProbeRsp)
3976 {
3977 mgmt->frame_control |=
3978 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3979 }
3980 else
3981 {
3982 mgmt->frame_control |=
3983 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003985
3986#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303987 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003988 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3989 {
3990 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3991 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303992 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3994
3995 {
3996 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3997 }
3998 else
3999 {
4000 kfree(mgmt);
4001 return NULL;
4002 }
4003#else
4004 freq = ieee80211_channel_to_frequency(chan_no);
4005#endif
4006 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004007 /*when the band is changed on the fly using the GUI, three things are done
4008 * 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)
4009 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4010 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4011 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4012 * and discards the channels correponding to previous band and calls back with zero bss results.
4013 * 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
4014 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4015 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4016 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4017 * So drop the bss and continue to next bss.
4018 */
4019 if(chan == NULL)
4020 {
4021 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004022 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004023 return NULL;
4024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304026 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004027 * */
4028 if (( eConnectionState_Associated ==
4029 pAdapter->sessionCtx.station.conn_info.connState ) &&
4030 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4031 pAdapter->sessionCtx.station.conn_info.bssId,
4032 WNI_CFG_BSSID_LEN)))
4033 {
4034 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4035 rssi = (pAdapter->rssi * 100);
4036 }
4037 else
4038 {
4039 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4040 }
4041
4042 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4043 frame_len, rssi, GFP_KERNEL);
4044 kfree(mgmt);
4045 return bss_status;
4046}
4047
4048/*
4049 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4050 * This function is used to update the BSS data base of CFG8011
4051 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304052struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 tCsrRoamInfo *pRoamInfo
4054 )
4055{
4056 tCsrRoamConnectedProfile roamProfile;
4057 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4058 struct cfg80211_bss *bss = NULL;
4059
4060 ENTER();
4061
4062 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4063 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4064
4065 if (NULL != roamProfile.pBssDesc)
4066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304067 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004068 &roamProfile);
4069
4070 if (NULL == bss)
4071 {
4072 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4073 __func__);
4074 }
4075
4076 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4077 }
4078 else
4079 {
4080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4081 __func__);
4082 }
4083 return bss;
4084}
4085
4086/*
4087 * FUNCTION: wlan_hdd_cfg80211_update_bss
4088 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304089static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4090 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092{
Jeff Johnson295189b2012-06-20 16:38:30 -07004093 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4094 tCsrScanResultInfo *pScanResult;
4095 eHalStatus status = 0;
4096 tScanResultHandle pResult;
4097 struct cfg80211_bss *bss_status = NULL;
4098
4099 ENTER();
4100
4101 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4102 {
4103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4104 return -EAGAIN;
4105 }
4106
4107 /*
4108 * start getting scan results and populate cgf80211 BSS database
4109 */
4110 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4111
4112 /* no scan results */
4113 if (NULL == pResult)
4114 {
4115 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4116 return status;
4117 }
4118
4119 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4120
4121 while (pScanResult)
4122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304123 /*
4124 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4125 * entry already exists in bss data base of cfg80211 for that
4126 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4127 * bss entry instead of cfg80211_inform_bss, But this call expects
4128 * mgmt packet as input. As of now there is no possibility to get
4129 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 * ieee80211_mgmt(probe response) and passing to c
4131 * fg80211_inform_bss_frame.
4132 * */
4133
4134 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4135 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304136
Jeff Johnson295189b2012-06-20 16:38:30 -07004137
4138 if (NULL == bss_status)
4139 {
4140 hddLog(VOS_TRACE_LEVEL_INFO,
4141 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4142 }
4143 else
4144 {
4145 cfg80211_put_bss(bss_status);
4146 }
4147
4148 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4149 }
4150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304151 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004152
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304153 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004154}
4155
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004156void
4157hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4158{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304159 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004160 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4161 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4162 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004163} /****** end hddPrintMacAddr() ******/
4164
4165void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004166hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004167{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304168 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004169 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4170 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4171 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4172 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004173} /****** end hddPrintPmkId() ******/
4174
4175//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4176//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4177
4178//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4179//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4180
4181#define dump_bssid(bssid) \
4182 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004183 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4184 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4185 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004186 }
4187
4188#define dump_pmkid(pMac, pmkid) \
4189 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004190 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4191 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4192 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004193 }
4194
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004195#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004196/*
4197 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4198 * This function is used to notify the supplicant of a new PMKSA candidate.
4199 */
4200int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304201 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004202 int index, bool preauth )
4203{
Jeff Johnsone7245742012-09-05 17:12:55 -07004204#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004205 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004206 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004207
4208 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004209 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004210
4211 if( NULL == pRoamInfo )
4212 {
4213 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4214 return -EINVAL;
4215 }
4216
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004217 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4218 {
4219 dump_bssid(pRoamInfo->bssid);
4220 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004221 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004222 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004223#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304224 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004225}
4226#endif //FEATURE_WLAN_LFR
4227
Jeff Johnson295189b2012-06-20 16:38:30 -07004228/*
4229 * FUNCTION: hdd_cfg80211_scan_done_callback
4230 * scanning callback function, called after finishing scan
4231 *
4232 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304233static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4235{
4236 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304237 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004239 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4240 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004241 struct cfg80211_scan_request *req = NULL;
4242 int ret = 0;
4243
4244 ENTER();
4245
4246 hddLog(VOS_TRACE_LEVEL_INFO,
4247 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304248 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 __func__, halHandle, pContext, (int) scanId, (int) status);
4250
4251 //Block on scan req completion variable. Can't wait forever though.
4252 ret = wait_for_completion_interruptible_timeout(
4253 &pScanInfo->scan_req_completion_event,
4254 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4255 if (!ret)
4256 {
4257 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004258 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 }
4260
4261 if(pScanInfo->mScanPending != VOS_TRUE)
4262 {
4263 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004264 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 }
4266
4267 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 {
4270 hddLog(VOS_TRACE_LEVEL_INFO,
4271 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304272 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 (int) scanId);
4274 }
4275
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304276 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004277 pAdapter);
4278
4279 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304280 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004281
4282
4283 /* If any client wait scan result through WEXT
4284 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004285 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004286 {
4287 /* The other scan request waiting for current scan finish
4288 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004289 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004290 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004291 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 }
4293 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004294 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004295 {
4296 struct net_device *dev = pAdapter->dev;
4297 union iwreq_data wrqu;
4298 int we_event;
4299 char *msg;
4300
4301 memset(&wrqu, '\0', sizeof(wrqu));
4302 we_event = SIOCGIWSCAN;
4303 msg = NULL;
4304 wireless_send_event(dev, we_event, &wrqu, msg);
4305 }
4306 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004307 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004308
4309 /* Get the Scan Req */
4310 req = pAdapter->request;
4311
4312 if (!req)
4313 {
4314 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004315 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004316 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 }
4318
4319 /*
4320 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304321 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004322 req->n_ssids = 0;
4323 req->n_channels = 0;
4324 req->ie = 0;
4325
Jeff Johnson295189b2012-06-20 16:38:30 -07004326 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004327 /* Scan is no longer pending */
4328 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004329
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004330 /*
4331 * cfg80211_scan_done informing NL80211 about completion
4332 * of scanning
4333 */
4334 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004335 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004336
Jeff Johnsone7245742012-09-05 17:12:55 -07004337allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004338 /* release the wake lock at the end of the scan*/
4339 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004340
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004341 /* Acquire wakelock to handle the case where APP's tries to suspend
4342 * immediatly after the driver gets connect request(i.e after scan)
4343 * from supplicant, this result in app's is suspending and not able
4344 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004345 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004346
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004347#ifdef FEATURE_WLAN_TDLS
4348 wlan_hdd_tdls_scan_done_callback(pAdapter);
4349#endif
4350
Jeff Johnson295189b2012-06-20 16:38:30 -07004351 EXIT();
4352 return 0;
4353}
4354
4355/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004356 * FUNCTION: hdd_isScanAllowed
4357 * Go through each adapter and check if scan allowed
4358 *
4359 */
4360v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4361{
4362 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4363 hdd_station_ctx_t *pHddStaCtx = NULL;
4364 hdd_adapter_t *pAdapter = NULL;
4365 VOS_STATUS status = 0;
4366 v_U8_t staId = 0;
4367 v_U8_t *staMac = NULL;
4368
Gopichand Nakkala8c0386c2013-07-09 23:31:37 +05304369 if (VOS_TIMER_STATE_RUNNING ==
4370 vos_timer_getCurrentState(&pHddCtx->hdd_p2p_go_conn_is_in_progress))
4371 {
4372 hddLog(VOS_TRACE_LEVEL_INFO,
4373 "%s: Connection is in progress, Do not allow the scan", __func__);
4374 return VOS_FALSE;
4375 }
4376
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004377 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4378
4379 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4380 {
4381 pAdapter = pAdapterNode->pAdapter;
4382
4383 if( pAdapter )
4384 {
4385 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304386 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004387 __func__, pAdapter->device_mode);
4388 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4389 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4390 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4391 {
4392 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4393 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4394 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4395 {
4396 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
4398 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304399 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004400 staMac[0], staMac[1], staMac[2],
4401 staMac[3], staMac[4], staMac[5]);
4402 return VOS_FALSE;
4403 }
4404 }
4405 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4406 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4407 {
4408 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304410 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004411 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4412 {
4413 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4414
4415 hddLog(VOS_TRACE_LEVEL_ERROR,
4416 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304417 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004418 staMac[0], staMac[1], staMac[2],
4419 staMac[3], staMac[4], staMac[5]);
4420 return VOS_FALSE;
4421 }
4422 }
4423 }
4424 }
4425 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4426 pAdapterNode = pNext;
4427 }
4428 hddLog(VOS_TRACE_LEVEL_INFO,
4429 "%s: Scan allowed", __func__);
4430 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304431}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004432
4433/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004434 * FUNCTION: wlan_hdd_cfg80211_scan
4435 * this scan respond to scan trigger and update cfg80211 scan database
4436 * later, scan dump command can be used to recieve scan results
4437 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004438int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4439#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4440 struct net_device *dev,
4441#endif
4442 struct cfg80211_scan_request *request)
4443{
4444#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4445 struct net_device *dev = request->wdev->netdev;
4446#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4449 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304450 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004451 tCsrScanRequest scanRequest;
4452 tANI_U8 *channelList = NULL, i;
4453 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304454 int status;
4455 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004457
4458 ENTER();
4459
4460 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4461 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004462
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304463 status = wlan_hdd_validate_context(pHddCtx);
4464
4465 if (0 != status)
4466 {
4467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4468 "%s: HDD context is not valid", __func__);
4469 return status;
4470 }
4471
4472 cfg_param = pHddCtx->cfg_ini;
4473 pScanInfo = &pHddCtx->scan_info;
4474
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004475 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004476 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004477 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004478 {
4479 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004480 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4481 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004482 return -EBUSY;
4483 }
4484
Jeff Johnson295189b2012-06-20 16:38:30 -07004485#ifdef WLAN_BTAMP_FEATURE
4486 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004487 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004489 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004490 "%s: No scanning when AMP is on", __func__);
4491 return -EOPNOTSUPP;
4492 }
4493#endif
4494 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004495 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004497 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004498 "%s: Not scanning on device_mode = %d",
4499 __func__, pAdapter->device_mode);
4500 return -EOPNOTSUPP;
4501 }
4502
4503 if (TRUE == pScanInfo->mScanPending)
4504 {
4505 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004506 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004507 }
4508
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304509 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004510 //Channel and action frame is pending
4511 //Otherwise Cancel Remain On Channel and allow Scan
4512 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004513 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004514 {
4515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4516 return -EBUSY;
4517 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004518#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004519 /* if tdls disagree scan right now, return immediately.
4520 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4521 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4522 */
4523 status = wlan_hdd_tdls_scan_callback (pAdapter,
4524 wiphy,
4525#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4526 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004527#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004528 request);
4529 if(status <= 0)
4530 {
4531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4532 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004533 }
4534#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004535
Jeff Johnson295189b2012-06-20 16:38:30 -07004536 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4537 {
4538 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004539 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004540 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4543 {
4544 hddLog(VOS_TRACE_LEVEL_WARN,
4545 "%s: MAX TM Level Scan not allowed", __func__);
4546 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304547 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 }
4549 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4550
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004551 /* Check if scan is allowed at this point of time.
4552 */
4553 if (!hdd_isScanAllowed(pHddCtx))
4554 {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4556 return -EBUSY;
4557 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304558
Jeff Johnson295189b2012-06-20 16:38:30 -07004559 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4560
4561 if (NULL != request)
4562 {
4563 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304564 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004565
4566 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4567 * Becasue of this, driver is assuming that this is not wildcard scan and so
4568 * is not aging out the scan results.
4569 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004570 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 {
4572 request->n_ssids = 0;
4573 }
4574
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004575 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004576 {
4577 tCsrSSIDInfo *SsidInfo;
4578 int j;
4579 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4580 /* Allocate num_ssid tCsrSSIDInfo structure */
4581 SsidInfo = scanRequest.SSIDs.SSIDList =
4582 ( tCsrSSIDInfo *)vos_mem_malloc(
4583 request->n_ssids*sizeof(tCsrSSIDInfo));
4584
4585 if(NULL == scanRequest.SSIDs.SSIDList)
4586 {
4587 hddLog(VOS_TRACE_LEVEL_ERROR,
4588 "memory alloc failed SSIDInfo buffer");
4589 return -ENOMEM;
4590 }
4591
4592 /* copy all the ssid's and their length */
4593 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4594 {
4595 /* get the ssid length */
4596 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4597 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4598 SsidInfo->SSID.length);
4599 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4600 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4601 j, SsidInfo->SSID.ssId);
4602 }
4603 /* set the scan type to active */
4604 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4605 }
4606 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4607 {
4608 /* set the scan type to active */
4609 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4610 }
4611 else
4612 {
4613 /*Set the scan type to default type, in this case it is ACTIVE*/
4614 scanRequest.scanType = pScanInfo->scan_mode;
4615 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304616 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004617 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4618 }
4619 else
4620 {
4621 /* set the scan type to active */
4622 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4623 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4624
4625 /* set min and max channel time to zero */
4626 scanRequest.minChnTime = 0;
4627 scanRequest.maxChnTime = 0;
4628 }
4629
4630 /* set BSSType to default type */
4631 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4632
4633 /*TODO: scan the requested channels only*/
4634
4635 /*Right now scanning all the channels */
4636 if( request )
4637 {
4638 if( request->n_channels )
4639 {
4640 channelList = vos_mem_malloc( request->n_channels );
4641 if( NULL == channelList )
4642 {
4643 status = -ENOMEM;
4644 goto free_mem;
4645 }
4646
4647 for( i = 0 ; i < request->n_channels ; i++ )
4648 channelList[i] = request->channels[i]->hw_value;
4649 }
4650
4651 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4652 scanRequest.ChannelInfo.ChannelList = channelList;
4653
4654 /* set requestType to full scan */
4655 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304656
4657 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004658 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304659 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004660 */
4661
4662 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304663 * and in that case driver shoudnt flush scan results. If
4664 * driver flushes the scan results here and unfortunately if
4665 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004666 * fails which is not desired
4667 */
4668
4669 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4670 {
4671 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4672 pAdapter->sessionId );
4673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004674
4675 if( request->ie_len )
4676 {
4677 /* save this for future association (join requires this) */
4678 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4679 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4680 pScanInfo->scanAddIE.length = request->ie_len;
4681
4682 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004683 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4684 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 )
4686 {
4687 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4688 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4689 }
4690
4691 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4692 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4693
Jeff Johnson295189b2012-06-20 16:38:30 -07004694 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4695 request->ie_len);
4696 if (pP2pIe != NULL)
4697 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004698#ifdef WLAN_FEATURE_P2P_DEBUG
4699 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4700 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4701 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4702 {
4703 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4704 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4705 "Go nego completed to Connection is started");
4706 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4707 "for 8way Handshake");
4708 }
4709 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4710 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4711 {
4712 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4713 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4714 "Disconnected state to Connection is started");
4715 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4716 "for 4way Handshake");
4717 }
4718#endif
4719
Jeff Johnsone7245742012-09-05 17:12:55 -07004720 /* no_cck will be set during p2p find to disable 11b rates */
4721 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004722 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004723 hddLog(VOS_TRACE_LEVEL_INFO,
4724 "%s: This is a P2P Search", __func__);
4725 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004726
Jeff Johnsone7245742012-09-05 17:12:55 -07004727 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4728 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004729 /* set requestType to P2P Discovery */
4730 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004731 }
4732
4733 /*
4734 Skip Dfs Channel in case of P2P Search
4735 if it is set in ini file
4736 */
4737 if(cfg_param->skipDfsChnlInP2pSearch)
4738 {
4739 scanRequest.skipDfsChnlInP2pSearch = 1;
4740 }
4741 else
4742 {
4743 scanRequest.skipDfsChnlInP2pSearch = 0;
4744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004745
Jeff Johnson295189b2012-06-20 16:38:30 -07004746 }
4747 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004748 }
4749 }
4750
4751 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4752
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004753 /* acquire the wakelock to avoid the apps suspend during the scan. To
4754 * address the following issues.
4755 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4756 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4757 * for long time, this result in apps running at full power for long time.
4758 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4759 * be stuck in full power because of resume BMPS
4760 */
4761 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004762
4763 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004764 pAdapter->sessionId, &scanRequest, &scanId,
4765 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004766
Jeff Johnson295189b2012-06-20 16:38:30 -07004767 if (eHAL_STATUS_SUCCESS != status)
4768 {
4769 hddLog(VOS_TRACE_LEVEL_ERROR,
4770 "%s: sme_ScanRequest returned error %d", __func__, status);
4771 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004772 if(eHAL_STATUS_RESOURCES == status)
4773 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004774 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 -07004775 status = -EBUSY;
4776 } else {
4777 status = -EIO;
4778 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004779 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 goto free_mem;
4781 }
4782
4783 pScanInfo->mScanPending = TRUE;
4784 pAdapter->request = request;
4785 pScanInfo->scanId = scanId;
4786
4787 complete(&pScanInfo->scan_req_completion_event);
4788
4789free_mem:
4790 if( scanRequest.SSIDs.SSIDList )
4791 {
4792 vos_mem_free(scanRequest.SSIDs.SSIDList);
4793 }
4794
4795 if( channelList )
4796 vos_mem_free( channelList );
4797
4798 EXIT();
4799
4800 return status;
4801}
4802
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004803
4804void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4805{
4806 v_U8_t iniDot11Mode =
4807 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4808 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4809
4810 switch ( iniDot11Mode )
4811 {
4812 case eHDD_DOT11_MODE_AUTO:
4813 case eHDD_DOT11_MODE_11ac:
4814 case eHDD_DOT11_MODE_11ac_ONLY:
4815#ifdef WLAN_FEATURE_11AC
4816 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4817#else
4818 hddDot11Mode = eHDD_DOT11_MODE_11n;
4819#endif
4820 break;
4821 case eHDD_DOT11_MODE_11n:
4822 case eHDD_DOT11_MODE_11n_ONLY:
4823 hddDot11Mode = eHDD_DOT11_MODE_11n;
4824 break;
4825 default:
4826 hddDot11Mode = iniDot11Mode;
4827 break;
4828 }
4829 /* This call decides required channel bonding mode */
4830 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4831 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4832 operationChannel);
4833}
4834
Jeff Johnson295189b2012-06-20 16:38:30 -07004835/*
4836 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304837 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004838 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304839int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004840 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004841{
4842 int status = 0;
4843 hdd_wext_state_t *pWextState;
4844 v_U32_t roamId;
4845 tCsrRoamProfile *pRoamProfile;
4846 eMib_dot11DesiredBssType connectedBssType;
4847 eCsrAuthType RSNAuthType;
4848
4849 ENTER();
4850
4851 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304852
Jeff Johnson295189b2012-06-20 16:38:30 -07004853 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4854 {
4855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4856 return -EINVAL;
4857 }
4858
4859 pRoamProfile = &pWextState->roamProfile;
4860
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304861 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004862 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004863 int ret = 0;
4864 hdd_station_ctx_t *pHddStaCtx;
4865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4866 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4867
4868 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4869 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4870 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 {
4872 /* Issue disconnect to CSR */
4873 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304874 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004875 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4876 pAdapter->sessionId,
4877 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4878 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004879 ret = wait_for_completion_interruptible_timeout(
4880 &pAdapter->disconnect_comp_var,
4881 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4882 if (0 == ret)
4883 {
4884 VOS_ASSERT(0);
4885 }
4886 }
4887 }
4888 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4889 {
4890 ret = wait_for_completion_interruptible_timeout(
4891 &pAdapter->disconnect_comp_var,
4892 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4893 if (0 == ret)
4894 {
4895 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 }
4897 }
4898
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304899 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004900 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4901 {
4902 /*QoS not enabled in cfg file*/
4903 pRoamProfile->uapsd_mask = 0;
4904 }
4905 else
4906 {
4907 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304908 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004909 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4910 }
4911
4912 pRoamProfile->SSIDs.numOfSSIDs = 1;
4913 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4914 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304915 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4917 ssid, ssid_len);
4918
4919 if (bssid)
4920 {
4921 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4922 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4923 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304924 /* Save BSSID in seperate variable as well, as RoamProfile
4925 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004926 case of join failure we should send valid BSSID to supplicant
4927 */
4928 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4929 WNI_CFG_BSSID_LEN);
4930 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07004931 else
4932 {
4933 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
4934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004935
4936 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4937 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304938 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 /*set gen ie*/
4940 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4941 /*set auth*/
4942 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004944#ifdef FEATURE_WLAN_WAPI
4945 if (pAdapter->wapi_info.nWapiMode)
4946 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004947 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 switch (pAdapter->wapi_info.wapiAuthMode)
4949 {
4950 case WAPI_AUTH_MODE_PSK:
4951 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004952 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 pAdapter->wapi_info.wapiAuthMode);
4954 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4955 break;
4956 }
4957 case WAPI_AUTH_MODE_CERT:
4958 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004959 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004960 pAdapter->wapi_info.wapiAuthMode);
4961 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4962 break;
4963 }
4964 } // End of switch
4965 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4966 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4967 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004968 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 pRoamProfile->AuthType.numEntries = 1;
4970 pRoamProfile->EncryptionType.numEntries = 1;
4971 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4972 pRoamProfile->mcEncryptionType.numEntries = 1;
4973 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4974 }
4975 }
4976#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304977#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05304978 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304979 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4980 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4981 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05304982 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
4983 sizeof (tSirGtkOffloadParams));
4984 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304985 }
4986#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 pRoamProfile->csrPersona = pAdapter->device_mode;
4988
Jeff Johnson32d95a32012-09-10 13:15:23 -07004989 if( operatingChannel )
4990 {
4991 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4992 pRoamProfile->ChannelInfo.numOfChannels = 1;
4993 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004994 else
4995 {
4996 pRoamProfile->ChannelInfo.ChannelList = NULL;
4997 pRoamProfile->ChannelInfo.numOfChannels = 0;
4998 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004999 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5000 {
5001 hdd_select_cbmode(pAdapter,operatingChannel);
5002 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005003 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5004 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305005 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005006 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005007 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5008 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305009 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5010 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005011 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5012 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305013
5014 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 pAdapter->sessionId, pRoamProfile, &roamId);
5016
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305017 if ((eHAL_STATUS_SUCCESS != status) &&
5018 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5019 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305020
5021 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5023 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5024 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305025 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005026 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305027 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005028
5029 pRoamProfile->ChannelInfo.ChannelList = NULL;
5030 pRoamProfile->ChannelInfo.numOfChannels = 0;
5031
Jeff Johnson295189b2012-06-20 16:38:30 -07005032 }
5033 else
5034 {
5035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5036 return -EINVAL;
5037 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005038 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 return status;
5040}
5041
5042/*
5043 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5044 * This function is used to set the authentication type (OPEN/SHARED).
5045 *
5046 */
5047static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5048 enum nl80211_auth_type auth_type)
5049{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305050 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5052
5053 ENTER();
5054
5055 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305056 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005058 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305059 hddLog(VOS_TRACE_LEVEL_INFO,
5060 "%s: set authentication type to AUTOSWITCH", __func__);
5061 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5062 break;
5063
5064 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005065#ifdef WLAN_FEATURE_VOWIFI_11R
5066 case NL80211_AUTHTYPE_FT:
5067#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305068 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005069 "%s: set authentication type to OPEN", __func__);
5070 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5071 break;
5072
5073 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305074 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005075 "%s: set authentication type to SHARED", __func__);
5076 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5077 break;
5078#ifdef FEATURE_WLAN_CCX
5079 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305080 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 "%s: set authentication type to CCKM WPA", __func__);
5082 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5083 break;
5084#endif
5085
5086
5087 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305088 hddLog(VOS_TRACE_LEVEL_ERROR,
5089 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 auth_type);
5091 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5092 return -EINVAL;
5093 }
5094
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305095 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 pHddStaCtx->conn_info.authType;
5097 return 0;
5098}
5099
5100/*
5101 * FUNCTION: wlan_hdd_set_akm_suite
5102 * This function is used to set the key mgmt type(PSK/8021x).
5103 *
5104 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 u32 key_mgmt
5107 )
5108{
5109 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5110 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305111
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 /*set key mgmt type*/
5113 switch(key_mgmt)
5114 {
5115 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305116#ifdef WLAN_FEATURE_VOWIFI_11R
5117 case WLAN_AKM_SUITE_FT_PSK:
5118#endif
5119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005120 __func__);
5121 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5122 break;
5123
5124 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305125#ifdef WLAN_FEATURE_VOWIFI_11R
5126 case WLAN_AKM_SUITE_FT_8021X:
5127#endif
5128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 __func__);
5130 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5131 break;
5132#ifdef FEATURE_WLAN_CCX
5133#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5134#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5135 case WLAN_AKM_SUITE_CCKM:
5136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5137 __func__);
5138 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5139 break;
5140#endif
5141
5142 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005144 __func__, key_mgmt);
5145 return -EINVAL;
5146
5147 }
5148 return 0;
5149}
5150
5151/*
5152 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005154 * (NONE/WEP40/WEP104/TKIP/CCMP).
5155 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305156static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5157 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 bool ucast
5159 )
5160{
5161 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305162 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5164
5165 ENTER();
5166
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305167 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005170 __func__, cipher);
5171 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5172 }
5173 else
5174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305175
Jeff Johnson295189b2012-06-20 16:38:30 -07005176 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305177 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 {
5179 case IW_AUTH_CIPHER_NONE:
5180 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5181 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305182
Jeff Johnson295189b2012-06-20 16:38:30 -07005183 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305184 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305186
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305188 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305190
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 case WLAN_CIPHER_SUITE_TKIP:
5192 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5193 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 case WLAN_CIPHER_SUITE_CCMP:
5196 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5197 break;
5198#ifdef FEATURE_WLAN_WAPI
5199 case WLAN_CIPHER_SUITE_SMS4:
5200 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5201 break;
5202#endif
5203
5204#ifdef FEATURE_WLAN_CCX
5205 case WLAN_CIPHER_SUITE_KRK:
5206 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5207 break;
5208#endif
5209 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 __func__, cipher);
5212 return -EOPNOTSUPP;
5213 }
5214 }
5215
5216 if (ucast)
5217 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 __func__, encryptionType);
5220 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5221 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305222 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 encryptionType;
5224 }
5225 else
5226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305227 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005228 __func__, encryptionType);
5229 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5230 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5231 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5232 }
5233
5234 return 0;
5235}
5236
5237
5238/*
5239 * FUNCTION: wlan_hdd_cfg80211_set_ie
5240 * This function is used to parse WPA/RSN IE's.
5241 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5243 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005244 size_t ie_len
5245 )
5246{
5247 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5248 u8 *genie = ie;
5249 v_U16_t remLen = ie_len;
5250#ifdef FEATURE_WLAN_WAPI
5251 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5252 u16 *tmp;
5253 v_U16_t akmsuiteCount;
5254 int *akmlist;
5255#endif
5256 ENTER();
5257
5258 /* clear previous assocAddIE */
5259 pWextState->assocAddIE.length = 0;
5260 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5261
5262 while (remLen >= 2)
5263 {
5264 v_U16_t eLen = 0;
5265 v_U8_t elementId;
5266 elementId = *genie++;
5267 eLen = *genie++;
5268 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269
5270 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305272
5273 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305275 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005276 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 -07005277 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305278 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 "%s: Invalid WPA IE", __func__);
5280 return -EINVAL;
5281 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305282 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 {
5284 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305285 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305287
Jeff Johnson295189b2012-06-20 16:38:30 -07005288 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5289 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005290 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5291 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005292 VOS_ASSERT(0);
5293 return -ENOMEM;
5294 }
5295 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5296 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5297 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305298
Jeff Johnson295189b2012-06-20 16:38:30 -07005299 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5300 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5301 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305303 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5304 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5306 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5307 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5308 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5309 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5310 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305311 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5312 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005313 /*Consider P2P IE, only for P2P Client */
5314 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5315 {
5316 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305317 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005318 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305319
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5321 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005322 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5323 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005324 VOS_ASSERT(0);
5325 return -ENOMEM;
5326 }
5327 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5328 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5329 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305330
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5332 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005334#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305335 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5336 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 /*Consider WFD IE, only for P2P Client */
5338 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5339 {
5340 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305341 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305343
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5345 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005346 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5347 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 VOS_ASSERT(0);
5349 return -ENOMEM;
5350 }
5351 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5352 // WPS IE + P2P IE + WFD IE
5353 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5354 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305355
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5357 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5358 }
5359#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005360 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305361 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005362 HS20_OUI_TYPE_SIZE)) )
5363 {
5364 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305365 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005366 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005367
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005368 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5369 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005370 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5371 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005372 VOS_ASSERT(0);
5373 return -ENOMEM;
5374 }
5375 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5376 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005377
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005378 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5379 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5380 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005381
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 break;
5383 case DOT11F_EID_RSN:
5384 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5385 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5386 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5387 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5388 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5389 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005390 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5391 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305392 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005393 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305394 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005395 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305396
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005397 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5398 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005399 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5400 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005401 VOS_ASSERT(0);
5402 return -ENOMEM;
5403 }
5404 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5405 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305406
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005407 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5408 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5409 break;
5410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005411#ifdef FEATURE_WLAN_WAPI
5412 case WLAN_EID_WAPI:
5413 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5414 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5415 pAdapter->wapi_info.nWapiMode);
5416 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305417 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 akmsuiteCount = WPA_GET_LE16(tmp);
5419 tmp = tmp + 1;
5420 akmlist = (int *)(tmp);
5421 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5422 {
5423 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5424 }
5425 else
5426 {
5427 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5428 VOS_ASSERT(0);
5429 return -EINVAL;
5430 }
5431
5432 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5433 {
5434 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005435 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305439 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005441 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5443 }
5444 break;
5445#endif
5446 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305447 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005449 /* when Unknown IE is received we should break and continue
5450 * to the next IE in the buffer instead we were returning
5451 * so changing this to break */
5452 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 }
5454 genie += eLen;
5455 remLen -= eLen;
5456 }
5457 EXIT();
5458 return 0;
5459}
5460
5461/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305462 * FUNCTION: hdd_isWPAIEPresent
5463 * Parse the received IE to find the WPA IE
5464 *
5465 */
5466static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5467{
5468 v_U8_t eLen = 0;
5469 v_U16_t remLen = ie_len;
5470 v_U8_t elementId = 0;
5471
5472 while (remLen >= 2)
5473 {
5474 elementId = *ie++;
5475 eLen = *ie++;
5476 remLen -= 2;
5477 if (eLen > remLen)
5478 {
5479 hddLog(VOS_TRACE_LEVEL_ERROR,
5480 "%s: IE length is wrong %d", __func__, eLen);
5481 return FALSE;
5482 }
5483 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5484 {
5485 /* OUI - 0x00 0X50 0XF2
5486 WPA Information Element - 0x01
5487 WPA version - 0x01*/
5488 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5489 return TRUE;
5490 }
5491 ie += eLen;
5492 remLen -= eLen;
5493 }
5494 return FALSE;
5495}
5496
5497/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305499 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 * parameters during connect operation.
5501 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305502int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 struct cfg80211_connect_params *req
5504 )
5505{
5506 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 ENTER();
5509
5510 /*set wpa version*/
5511 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5512
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305513 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05305515 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 {
5517 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5518 }
5519 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5520 {
5521 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5522 }
5523 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305524
5525 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 pWextState->wpaVersion);
5527
5528 /*set authentication type*/
5529 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5530
5531 if (0 > status)
5532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305533 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 "%s: failed to set authentication type ", __func__);
5535 return status;
5536 }
5537
5538 /*set key mgmt type*/
5539 if (req->crypto.n_akm_suites)
5540 {
5541 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5542 if (0 > status)
5543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 __func__);
5546 return status;
5547 }
5548 }
5549
5550 /*set pairwise cipher type*/
5551 if (req->crypto.n_ciphers_pairwise)
5552 {
5553 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5554 req->crypto.ciphers_pairwise[0], true);
5555 if (0 > status)
5556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 "%s: failed to set unicast cipher type", __func__);
5559 return status;
5560 }
5561 }
5562 else
5563 {
5564 /*Reset previous cipher suite to none*/
5565 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5566 if (0 > status)
5567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 "%s: failed to set unicast cipher type", __func__);
5570 return status;
5571 }
5572 }
5573
5574 /*set group cipher type*/
5575 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5576 false);
5577
5578 if (0 > status)
5579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 __func__);
5582 return status;
5583 }
5584
Chet Lanctot186b5732013-03-18 10:26:30 -07005585#ifdef WLAN_FEATURE_11W
5586 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5587#endif
5588
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5590 if (req->ie_len)
5591 {
5592 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5593 if ( 0 > status)
5594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 __func__);
5597 return status;
5598 }
5599 }
5600
5601 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305602 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 {
5604 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5605 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5606 )
5607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5610 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 __func__);
5613 return -EOPNOTSUPP;
5614 }
5615 else
5616 {
5617 u8 key_len = req->key_len;
5618 u8 key_idx = req->key_idx;
5619
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305620 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 && (CSR_MAX_NUM_KEY > key_idx)
5622 )
5623 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305624 hddLog(VOS_TRACE_LEVEL_INFO,
5625 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 __func__, key_idx, key_len);
5627 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305628 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305630 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 (u8)key_len;
5632 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5633 }
5634 }
5635 }
5636 }
5637
5638 return status;
5639}
5640
5641/*
5642 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305643 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 * parameters during connect operation.
5645 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 struct net_device *ndev,
5648 struct cfg80211_connect_params *req
5649 )
5650{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305651 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305652 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5654 hdd_context_t *pHddCtx = NULL;
5655
5656 ENTER();
5657
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305658 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5660
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5662 status = wlan_hdd_validate_context(pHddCtx);
5663
5664 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5667 "%s: HDD context is not valid", __func__);
5668 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 }
5670
5671#ifdef WLAN_BTAMP_FEATURE
5672 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305673 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305675 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005676 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005677 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 }
5679#endif
5680 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305681 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005682
5683 if ( 0 > status)
5684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 __func__);
5687 return status;
5688 }
5689
5690 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005691 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5693 (vos_concurrent_sessions_running()))
5694 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305695 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 }
5697
Mohit Khanna765234a2012-09-11 15:08:35 -07005698 if ( req->channel )
5699 {
5700 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5701 req->ssid_len, req->bssid,
5702 req->channel->hw_value);
5703 }
5704 else
5705 {
5706 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305707 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005708 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005709
5710 if (0 > status)
5711 {
5712 //ReEnable BMPS if disabled
5713 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5714 (NULL != pHddCtx))
5715 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305716 if (pHddCtx->hdd_wlan_suspended)
5717 {
5718 hdd_set_pwrparams(pHddCtx);
5719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 //ReEnable Bmps and Imps back
5721 hdd_enable_bmps_imps(pHddCtx);
5722 }
5723
5724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5725 return status;
5726 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305727 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 EXIT();
5729 return status;
5730}
5731
5732
5733/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305734 * FUNCTION: wlan_hdd_disconnect
5735 * This function is used to issue a disconnect request to SME
5736 */
5737int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5738{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305739 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305740 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305741 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5742
5743 status = wlan_hdd_validate_context(pHddCtx);
5744
5745 if (0 != status)
5746 {
5747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5748 "%s: HDD context is not valid", __func__);
5749 return status;
5750 }
5751
5752 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305753 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305754 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305755
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305756 /*issue disconnect*/
5757 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5758 pAdapter->sessionId, reason);
5759
5760 if ( 0 != status )
5761 {
5762 hddLog(VOS_TRACE_LEVEL_ERROR,
5763 "%s csrRoamDisconnect failure, returned %d \n",
5764 __func__, (int)status );
5765 return -EINVAL;
5766 }
5767 wait_for_completion_interruptible_timeout(
5768 &pAdapter->disconnect_comp_var,
5769 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5770 /*stop tx queues*/
5771 netif_tx_disable(pAdapter->dev);
5772 netif_carrier_off(pAdapter->dev);
5773 return status;
5774}
5775
5776
5777/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 * FUNCTION: wlan_hdd_cfg80211_disconnect
5779 * This function is used to issue a disconnect request to SME
5780 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 struct net_device *dev,
5783 u16 reason
5784 )
5785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5787 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305789 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005791 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305792#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005793 tANI_U8 staIdx;
5794#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305795
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797
5798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 __func__,pAdapter->device_mode);
5800
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5802 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305804 status = wlan_hdd_validate_context(pHddCtx);
5805
5806 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5809 "%s: HDD context is not valid", __func__);
5810 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305812
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 if (NULL != pRoamProfile)
5814 {
5815 /*issue disconnect request to SME, if station is in connected state*/
5816 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305818 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305820 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 switch(reason)
5822 {
5823 case WLAN_REASON_MIC_FAILURE:
5824 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5825 break;
5826
5827 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5828 case WLAN_REASON_DISASSOC_AP_BUSY:
5829 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5830 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5831 break;
5832
5833 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5834 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5835 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5836 break;
5837
5838 case WLAN_REASON_DEAUTH_LEAVING:
5839 default:
5840 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5841 break;
5842 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305843 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5844 pScanInfo = &pHddCtx->scan_info;
5845 if (pScanInfo->mScanPending)
5846 {
5847 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5848 "Aborting Scan");
5849 hdd_abort_mac_scan(pHddCtx);
5850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005851
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005852#ifdef FEATURE_WLAN_TDLS
5853 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005854 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005855 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005856 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5857 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005858 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005859 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005860 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005861 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005862 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005863 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005864 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005865 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005866 pAdapter->sessionId,
5867 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005868 }
5869 }
5870#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305871 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5872 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 {
5874 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305875 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 __func__, (int)status );
5877 return -EINVAL;
5878 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 }
5880 }
5881 else
5882 {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5884 }
5885
5886 return status;
5887}
5888
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305889
Jeff Johnson295189b2012-06-20 16:38:30 -07005890/*
5891 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 * settings in IBSS mode.
5894 */
5895static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305896 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005897 struct cfg80211_ibss_params *params
5898 )
5899{
5900 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 ENTER();
5906
5907 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5908
5909 if (params->ie_len && ( NULL != params->ie) )
5910 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07005911 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
5912 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 {
5914 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5915 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5916 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07005917 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005919 tDot11fIEWPA dot11WPAIE;
5920 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07005921 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005922
Shailender Karmuchi67edd312013-06-18 16:30:48 -07005923 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
5924 params->ie_len, DOT11F_EID_WPA);
5925 if ( NULL != ie )
5926 {
5927 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5928 // Unpack the WPA IE
5929 //Skip past the EID byte and length byte - and four byte WiFi OUI
5930 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
5931 &ie[2+4],
5932 ie[1] - 4,
5933 &dot11WPAIE);
5934 /*Extract the multicast cipher, the encType for unicast
5935 cipher for wpa-none is none*/
5936 encryptionType =
5937 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
5938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07005940
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5942
5943 if (0 > status)
5944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 __func__);
5947 return status;
5948 }
5949 }
5950
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305951 pWextState->roamProfile.AuthType.authType[0] =
5952 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5954
5955 if (params->privacy)
5956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305957 /* Security enabled IBSS, At this time there is no information available
5958 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005959 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305960 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305962 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 *enable privacy bit in beacons */
5964
5965 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5966 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07005967 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5968 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5970 pWextState->roamProfile.EncryptionType.numEntries = 1;
5971 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 return status;
5973}
5974
5975/*
5976 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305979static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 struct net_device *dev,
5981 struct cfg80211_ibss_params *params
5982 )
5983{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5986 tCsrRoamProfile *pRoamProfile;
5987 int status;
5988 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305989 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005990
5991 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305992
5993 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5995
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305996 status = wlan_hdd_validate_context(pHddCtx);
5997
5998 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6001 "%s: HDD context is not valid", __func__);
6002 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 }
6004
6005 if (NULL == pWextState)
6006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006008 __func__);
6009 return -EIO;
6010 }
6011
6012 pRoamProfile = &pWextState->roamProfile;
6013
6014 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6015 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306016 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 "%s Interface type is not set to IBSS \n", __func__);
6018 return -EINVAL;
6019 }
6020
6021 /* Set Channel */
6022 if (NULL != params->channel)
6023 {
6024 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006025 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6026 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6027 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6028 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006029
6030 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306031 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 ieee80211_frequency_to_channel(params->channel->center_freq);
6033
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006034
6035 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6036 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6039 __func__);
6040 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006042
6043 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006045 if (channelNum == validChan[indx])
6046 {
6047 break;
6048 }
6049 }
6050 if (indx >= numChans)
6051 {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 __func__, channelNum);
6054 return -EINVAL;
6055 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006056 /* Set the Operational Channel */
6057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6058 channelNum);
6059 pRoamProfile->ChannelInfo.numOfChannels = 1;
6060 pHddStaCtx->conn_info.operationChannel = channelNum;
6061 pRoamProfile->ChannelInfo.ChannelList =
6062 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 }
6064
6065 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306066 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 if (status < 0)
6068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 __func__);
6071 return status;
6072 }
6073
6074 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306075 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006076 params->ssid_len, params->bssid,
6077 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006078
6079 if (0 > status)
6080 {
6081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6082 return status;
6083 }
6084
6085 return 0;
6086}
6087
6088/*
6089 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306090 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306092static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 struct net_device *dev
6094 )
6095{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6098 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6100 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006101
6102 ENTER();
6103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306104 status = wlan_hdd_validate_context(pHddCtx);
6105
6106 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6109 "%s: HDD context is not valid", __func__);
6110 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006111 }
6112
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
6114 if (NULL == pWextState)
6115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306116 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 __func__);
6118 return -EIO;
6119 }
6120
6121 pRoamProfile = &pWextState->roamProfile;
6122
6123 /* Issue disconnect only if interface type is set to IBSS */
6124 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 __func__);
6128 return -EINVAL;
6129 }
6130
6131 /* Issue Disconnect request */
6132 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6133 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6134 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6135
6136 return 0;
6137}
6138
6139/*
6140 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6141 * This function is used to set the phy parameters
6142 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6143 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306144static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006145 u32 changed)
6146{
6147 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6148 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306149 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006150
6151 ENTER();
6152
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306153 status = wlan_hdd_validate_context(pHddCtx);
6154
6155 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6158 "%s: HDD context is not valid", __func__);
6159 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006160 }
6161
Jeff Johnson295189b2012-06-20 16:38:30 -07006162 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6163 {
6164 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6165 WNI_CFG_RTS_THRESHOLD_STAMAX :
6166 wiphy->rts_threshold;
6167
6168 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306169 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306171 hddLog(VOS_TRACE_LEVEL_ERROR,
6172 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 __func__, rts_threshold);
6174 return -EINVAL;
6175 }
6176
6177 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6178 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306179 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181 hddLog(VOS_TRACE_LEVEL_ERROR,
6182 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 __func__, rts_threshold);
6184 return -EIO;
6185 }
6186
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306187 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 rts_threshold);
6189 }
6190
6191 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6192 {
6193 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6194 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6195 wiphy->frag_threshold;
6196
6197 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306198 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306200 hddLog(VOS_TRACE_LEVEL_ERROR,
6201 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 frag_threshold);
6203 return -EINVAL;
6204 }
6205
6206 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6207 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306208 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306210 hddLog(VOS_TRACE_LEVEL_ERROR,
6211 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 __func__, frag_threshold);
6213 return -EIO;
6214 }
6215
6216 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6217 frag_threshold);
6218 }
6219
6220 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6221 || (changed & WIPHY_PARAM_RETRY_LONG))
6222 {
6223 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6224 wiphy->retry_short :
6225 wiphy->retry_long;
6226
6227 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6228 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 __func__, retry_value);
6232 return -EINVAL;
6233 }
6234
6235 if (changed & WIPHY_PARAM_RETRY_SHORT)
6236 {
6237 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6238 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306239 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306241 hddLog(VOS_TRACE_LEVEL_ERROR,
6242 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 __func__, retry_value);
6244 return -EIO;
6245 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306246 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 __func__, retry_value);
6248 }
6249 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6250 {
6251 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6252 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306253 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306255 hddLog(VOS_TRACE_LEVEL_ERROR,
6256 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 __func__, retry_value);
6258 return -EIO;
6259 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306260 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 __func__, retry_value);
6262 }
6263 }
6264
6265 return 0;
6266}
6267
6268/*
6269 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6270 * This function is used to set the txpower
6271 */
6272static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6273#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306274 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006275#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306276 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006277#endif
6278 int dbm)
6279{
6280 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306281 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6283 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306284 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006285
6286 ENTER();
6287
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306288 status = wlan_hdd_validate_context(pHddCtx);
6289
6290 if (0 != status)
6291 {
6292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6293 "%s: HDD context is not valid", __func__);
6294 return status;
6295 }
6296
6297 hHal = pHddCtx->hHal;
6298
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306299 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6300 dbm, ccmCfgSetCallback,
6301 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6305 return -EIO;
6306 }
6307
6308 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6309 dbm);
6310
6311 switch(type)
6312 {
6313 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6314 /* Fall through */
6315 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6316 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6319 __func__);
6320 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 }
6322 break;
6323 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 __func__);
6326 return -EOPNOTSUPP;
6327 break;
6328 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6330 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 return -EIO;
6332 }
6333
6334 return 0;
6335}
6336
6337/*
6338 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6339 * This function is used to read the txpower
6340 */
6341static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6342{
6343
6344 hdd_adapter_t *pAdapter;
6345 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306346 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006347
Jeff Johnsone7245742012-09-05 17:12:55 -07006348 ENTER();
6349
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306350 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306352 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006353 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6355 "%s: HDD context is not valid", __func__);
6356 *dbm = 0;
6357 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006358 }
6359
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6361 if (NULL == pAdapter)
6362 {
6363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6364 return -ENOENT;
6365 }
6366
6367 wlan_hdd_get_classAstats(pAdapter);
6368 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6369
Jeff Johnsone7245742012-09-05 17:12:55 -07006370 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 return 0;
6372}
6373
6374static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6375 u8* mac, struct station_info *sinfo)
6376{
6377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6378 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6379 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6380 tANI_U8 rate_flags;
6381
6382 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6383 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006384
6385 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6386 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6387 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6388 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6389 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6390 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6391 tANI_U16 maxRate = 0;
6392 tANI_U16 myRate;
6393 tANI_U16 currentRate = 0;
6394 tANI_U8 maxSpeedMCS = 0;
6395 tANI_U8 maxMCSIdx = 0;
6396 tANI_U8 rateFlag = 1;
6397 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006398 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306399 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006400
Leo Chang6f8870f2013-03-26 18:11:36 -07006401#ifdef WLAN_FEATURE_11AC
6402 tANI_U32 vht_mcs_map;
6403 eDataRate11ACMaxMcs vhtMaxMcs;
6404#endif /* WLAN_FEATURE_11AC */
6405
Jeff Johnsone7245742012-09-05 17:12:55 -07006406 ENTER();
6407
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6409 (0 == ssidlen))
6410 {
6411 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6412 " Invalid ssidlen, %d", __func__, ssidlen);
6413 /*To keep GUI happy*/
6414 return 0;
6415 }
6416
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306417 status = wlan_hdd_validate_context(pHddCtx);
6418
6419 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6422 "%s: HDD context is not valid", __func__);
6423 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006424 }
6425
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6427 sinfo->filled |= STATION_INFO_SIGNAL;
6428
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006429 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6431
6432 //convert to the UI units of 100kbps
6433 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6434
6435#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006436 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 -07006437 sinfo->signal,
6438 pCfg->reportMaxLinkSpeed,
6439 myRate,
6440 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006441 (int) pCfg->linkSpeedRssiMid,
6442 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006443 (int) rate_flags,
6444 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006445#endif //LINKSPEED_DEBUG_ENABLED
6446
6447 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6448 {
6449 // we do not want to necessarily report the current speed
6450 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6451 {
6452 // report the max possible speed
6453 rssidx = 0;
6454 }
6455 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6456 {
6457 // report the max possible speed with RSSI scaling
6458 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6459 {
6460 // report the max possible speed
6461 rssidx = 0;
6462 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006463 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 {
6465 // report middle speed
6466 rssidx = 1;
6467 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006468 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6469 {
6470 // report middle speed
6471 rssidx = 2;
6472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 else
6474 {
6475 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006476 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 }
6478 }
6479 else
6480 {
6481 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6482 hddLog(VOS_TRACE_LEVEL_ERROR,
6483 "%s: Invalid value for reportMaxLinkSpeed: %u",
6484 __func__, pCfg->reportMaxLinkSpeed);
6485 rssidx = 0;
6486 }
6487
6488 maxRate = 0;
6489
6490 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306491 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6492 OperationalRates, &ORLeng))
6493 {
6494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6495 /*To keep GUI happy*/
6496 return 0;
6497 }
6498
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 for (i = 0; i < ORLeng; i++)
6500 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006501 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 {
6503 /* Validate Rate Set */
6504 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6505 {
6506 currentRate = supported_data_rate[j].supported_rate[rssidx];
6507 break;
6508 }
6509 }
6510 /* Update MAX rate */
6511 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6512 }
6513
6514 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306515 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6516 ExtendedRates, &ERLeng))
6517 {
6518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6519 /*To keep GUI happy*/
6520 return 0;
6521 }
6522
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 for (i = 0; i < ERLeng; i++)
6524 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006525 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 {
6527 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6528 {
6529 currentRate = supported_data_rate[j].supported_rate[rssidx];
6530 break;
6531 }
6532 }
6533 /* Update MAX rate */
6534 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006536 /* Get MCS Rate Set -- but only if we are connected at MCS
6537 rates or if we are always reporting max speed or if we have
6538 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006539 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306541 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6542 MCSRates, &MCSLeng))
6543 {
6544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6545 /*To keep GUI happy*/
6546 return 0;
6547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006549#ifdef WLAN_FEATURE_11AC
6550 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306551 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006553 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306554 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006555 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006557 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006559 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006561 maxMCSIdx = 7;
6562 }
6563 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6564 {
6565 maxMCSIdx = 8;
6566 }
6567 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6568 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306569 //VHT20 is supporting 0~8
6570 if (rate_flags & eHAL_TX_RATE_VHT20)
6571 maxMCSIdx = 8;
6572 else
6573 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006574 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306575
6576 if (rate_flags & eHAL_TX_RATE_VHT80)
6577 {
6578 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6579 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6580 }
6581 else if (rate_flags & eHAL_TX_RATE_VHT40)
6582 {
6583 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6584 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6585 }
6586 else if (rate_flags & eHAL_TX_RATE_VHT20)
6587 {
6588 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6589 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6590 }
6591
Leo Chang6f8870f2013-03-26 18:11:36 -07006592 maxSpeedMCS = 1;
6593 if (currentRate > maxRate)
6594 {
6595 maxRate = currentRate;
6596 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306597
Leo Chang6f8870f2013-03-26 18:11:36 -07006598 }
6599 else
6600#endif /* WLAN_FEATURE_11AC */
6601 {
6602 if (rate_flags & eHAL_TX_RATE_HT40)
6603 {
6604 rateFlag |= 1;
6605 }
6606 if (rate_flags & eHAL_TX_RATE_SGI)
6607 {
6608 rateFlag |= 2;
6609 }
6610
6611 for (i = 0; i < MCSLeng; i++)
6612 {
6613 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6614 for (j = 0; j < temp; j++)
6615 {
6616 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6617 {
6618 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6619 break;
6620 }
6621 }
6622 if ((j < temp) && (currentRate > maxRate))
6623 {
6624 maxRate = currentRate;
6625 maxSpeedMCS = 1;
6626 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6627 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 }
6629 }
6630 }
6631
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306632 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6633 {
6634 maxRate = myRate;
6635 maxSpeedMCS = 1;
6636 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6637 }
6638
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006640 if (((maxRate < myRate) && (0 == rssidx)) ||
6641 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 {
6643 maxRate = myRate;
6644 if (rate_flags & eHAL_TX_RATE_LEGACY)
6645 {
6646 maxSpeedMCS = 0;
6647 }
6648 else
6649 {
6650 maxSpeedMCS = 1;
6651 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6652 }
6653 }
6654
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306655 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 {
6657 sinfo->txrate.legacy = maxRate;
6658#ifdef LINKSPEED_DEBUG_ENABLED
6659 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6660#endif //LINKSPEED_DEBUG_ENABLED
6661 }
6662 else
6663 {
6664 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006665#ifdef WLAN_FEATURE_11AC
6666 sinfo->txrate.nss = 1;
6667 if (rate_flags & eHAL_TX_RATE_VHT80)
6668 {
6669 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306670 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006671 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306672 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006673 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306674 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6675 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6676 }
6677 else if (rate_flags & eHAL_TX_RATE_VHT20)
6678 {
6679 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6680 }
6681#endif /* WLAN_FEATURE_11AC */
6682 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6683 {
6684 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6685 if (rate_flags & eHAL_TX_RATE_HT40)
6686 {
6687 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6688 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 if (rate_flags & eHAL_TX_RATE_SGI)
6691 {
6692 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6693 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306694
Jeff Johnson295189b2012-06-20 16:38:30 -07006695#ifdef LINKSPEED_DEBUG_ENABLED
6696 pr_info("Reporting MCS rate %d flags %x\n",
6697 sinfo->txrate.mcs,
6698 sinfo->txrate.flags );
6699#endif //LINKSPEED_DEBUG_ENABLED
6700 }
6701 }
6702 else
6703 {
6704 // report current rate instead of max rate
6705
6706 if (rate_flags & eHAL_TX_RATE_LEGACY)
6707 {
6708 //provide to the UI in units of 100kbps
6709 sinfo->txrate.legacy = myRate;
6710#ifdef LINKSPEED_DEBUG_ENABLED
6711 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6712#endif //LINKSPEED_DEBUG_ENABLED
6713 }
6714 else
6715 {
6716 //must be MCS
6717 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006718#ifdef WLAN_FEATURE_11AC
6719 sinfo->txrate.nss = 1;
6720 if (rate_flags & eHAL_TX_RATE_VHT80)
6721 {
6722 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6723 }
6724 else
6725#endif /* WLAN_FEATURE_11AC */
6726 {
6727 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 if (rate_flags & eHAL_TX_RATE_SGI)
6730 {
6731 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6732 }
6733 if (rate_flags & eHAL_TX_RATE_HT40)
6734 {
6735 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6736 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006737#ifdef WLAN_FEATURE_11AC
6738 else if (rate_flags & eHAL_TX_RATE_VHT80)
6739 {
6740 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6741 }
6742#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006743#ifdef LINKSPEED_DEBUG_ENABLED
6744 pr_info("Reporting actual MCS rate %d flags %x\n",
6745 sinfo->txrate.mcs,
6746 sinfo->txrate.flags );
6747#endif //LINKSPEED_DEBUG_ENABLED
6748 }
6749 }
6750 sinfo->filled |= STATION_INFO_TX_BITRATE;
6751
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006752 sinfo->tx_packets =
6753 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6754 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6755 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6756 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6757
6758 sinfo->tx_retries =
6759 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6760 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6761 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6762 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6763
6764 sinfo->tx_failed =
6765 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6766 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6767 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6768 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6769
6770 sinfo->filled |=
6771 STATION_INFO_TX_PACKETS |
6772 STATION_INFO_TX_RETRIES |
6773 STATION_INFO_TX_FAILED;
6774
6775 EXIT();
6776 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006777}
6778
6779static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07006780 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07006781{
6782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306783 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306785 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006786
Jeff Johnsone7245742012-09-05 17:12:55 -07006787 ENTER();
6788
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 if (NULL == pAdapter)
6790 {
6791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6792 return -ENODEV;
6793 }
6794
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306795 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306796 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306797
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306798 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6801 "%s: HDD context is not valid", __func__);
6802 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306803 }
6804
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306805 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6806 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6807 (pHddCtx->cfg_ini->fhostArpOffload) &&
6808 (eConnectionState_Associated ==
6809 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6810 {
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05306811 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306812 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6813 {
6814 hddLog(VOS_TRACE_LEVEL_INFO,
6815 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6816 __func__, vos_status);
6817 }
6818 }
6819
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 /**The get power cmd from the supplicant gets updated by the nl only
6821 *on successful execution of the function call
6822 *we are oppositely mapped w.r.t mode in the driver
6823 **/
6824 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6825
Jeff Johnsone7245742012-09-05 17:12:55 -07006826 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 if (VOS_STATUS_E_FAILURE == vos_status)
6828 {
6829 return -EINVAL;
6830 }
6831 return 0;
6832}
6833
6834
6835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6836static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6837 struct net_device *netdev,
6838 u8 key_index)
6839{
Jeff Johnsone7245742012-09-05 17:12:55 -07006840 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 return 0;
6842}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306843#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006844
6845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6846static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6847 struct net_device *dev,
6848 struct ieee80211_txq_params *params)
6849{
Jeff Johnsone7245742012-09-05 17:12:55 -07006850 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 return 0;
6852}
6853#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6854static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6855 struct ieee80211_txq_params *params)
6856{
Jeff Johnsone7245742012-09-05 17:12:55 -07006857 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 return 0;
6859}
6860#endif //LINUX_VERSION_CODE
6861
6862static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6863 struct net_device *dev, u8 *mac)
6864{
6865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306866 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006867 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306868 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006869 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006870
Jeff Johnsone7245742012-09-05 17:12:55 -07006871 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306872 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 return -EINVAL;
6876 }
6877
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6879 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306881 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6884 "%s: HDD context is not valid", __func__);
6885 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006886 }
6887
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006890 )
6891 {
6892 if( NULL == mac )
6893 {
6894 v_U16_t i;
6895 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6896 {
6897 if(pAdapter->aStaInfo[i].isUsed)
6898 {
6899 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6900 hddLog(VOS_TRACE_LEVEL_INFO,
6901 "%s: Delete STA with MAC::"
6902 "%02x:%02x:%02x:%02x:%02x:%02x",
6903 __func__,
6904 macAddr[0], macAddr[1], macAddr[2],
6905 macAddr[3], macAddr[4], macAddr[5]);
6906 hdd_softap_sta_deauth(pAdapter, macAddr);
6907 }
6908 }
6909 }
6910 else
6911 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006912
6913 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6914 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6915 {
6916 hddLog(VOS_TRACE_LEVEL_INFO,
6917 "%s: Skip this DEL STA as this is not used::"
6918 "%02x:%02x:%02x:%02x:%02x:%02x",
6919 __func__,
6920 mac[0], mac[1], mac[2],
6921 mac[3], mac[4], mac[5]);
6922 return -ENOENT;
6923 }
6924
6925 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6926 {
6927 hddLog(VOS_TRACE_LEVEL_INFO,
6928 "%s: Skip this DEL STA as deauth is in progress::"
6929 "%02x:%02x:%02x:%02x:%02x:%02x",
6930 __func__,
6931 mac[0], mac[1], mac[2],
6932 mac[3], mac[4], mac[5]);
6933 return -ENOENT;
6934 }
6935
6936 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6937
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 hddLog(VOS_TRACE_LEVEL_INFO,
6939 "%s: Delete STA with MAC::"
6940 "%02x:%02x:%02x:%02x:%02x:%02x",
6941 __func__,
6942 mac[0], mac[1], mac[2],
6943 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006944
6945 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6946 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6947 {
6948 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6949 hddLog(VOS_TRACE_LEVEL_INFO,
6950 "%s: STA removal failed for ::"
6951 "%02x:%02x:%02x:%02x:%02x:%02x",
6952 __func__,
6953 mac[0], mac[1], mac[2],
6954 mac[3], mac[4], mac[5]);
6955 return -ENOENT;
6956 }
6957
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 }
6959 }
6960
6961 EXIT();
6962
6963 return 0;
6964}
6965
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006966static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6967 struct net_device *dev, u8 *mac, struct station_parameters *params)
6968{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006969 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006970#ifdef FEATURE_WLAN_TDLS
6971 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006972 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006973 mask = params->sta_flags_mask;
6974
6975 set = params->sta_flags_set;
6976
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006977#ifdef WLAN_FEATURE_TDLS_DEBUG
6978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6979 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6980 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6981#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006982
6983 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6984 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006985 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006986 }
6987 }
6988#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006989 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006990}
6991
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992
6993#ifdef FEATURE_WLAN_LFR
6994static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006995 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006996{
6997#define MAX_PMKSAIDS_IN_CACHE 8
6998 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999 static tANI_U32 i; // HDD Local Cache index
7000 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7002 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307003 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307004 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007005 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307006 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307007
Jeff Johnsone7245742012-09-05 17:12:55 -07007008 ENTER();
7009
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307010 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307011 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007014 return -EINVAL;
7015 }
7016
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307017 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7018 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307020 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007021 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7023 "%s: HDD context is not valid", __func__);
7024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007025 }
7026
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307027 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007028 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7029
7030 for (j = 0; j < i; j++)
7031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307032 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007033 pmksa->bssid, WNI_CFG_BSSID_LEN))
7034 {
7035 /* BSSID matched previous entry. Overwrite it. */
7036 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307037 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007038 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307039 vos_mem_copy(PMKIDCache[j].PMKID,
7040 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007041 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007043 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007044 dump_bssid(pmksa->bssid);
7045 dump_pmkid(halHandle, pmksa->pmkid);
7046 break;
7047 }
7048 }
7049
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007050 /* Check we compared all entries,if then take the first slot now */
7051 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
7052
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007053 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307054 {
7055 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
7056 vos_mem_copy(PMKIDCache[i].BSSID,
7057 pmksa->bssid, ETHER_ADDR_LEN);
7058 vos_mem_copy(PMKIDCache[i].PMKID,
7059 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007060 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007062 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007063 dump_bssid(pmksa->bssid);
7064 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307065 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007066 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307067 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007068 }
7069
7070
7071 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307072 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007073 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307074 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007075 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007076 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307077 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7078 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007079 i );
7080 return 0;
7081}
7082
7083
7084static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007085 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007086{
Jeff Johnsone7245742012-09-05 17:12:55 -07007087 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007088 // TODO: Implement this later.
7089 return 0;
7090}
7091
7092static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7093{
Jeff Johnsone7245742012-09-05 17:12:55 -07007094 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007095 // TODO: Implement this later.
7096 return 0;
7097}
7098#endif
7099
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007100#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307101static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007102 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
7103{
7104 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7105 hdd_station_ctx_t *pHddStaCtx;
7106
7107 if (NULL == pAdapter)
7108 {
7109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
7110 return -ENODEV;
7111 }
7112
7113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7114
7115 // Added for debug on reception of Re-assoc Req.
7116 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307118 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007119 ftie->ie_len);
7120 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7121 }
7122
7123#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307124 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007125 ftie->ie_len);
7126#endif
7127
7128 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307129 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7130 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007131 ftie->ie_len);
7132 return 0;
7133}
7134#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007135
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307136#ifdef FEATURE_WLAN_SCAN_PNO
7137
7138void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7139 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7140{
7141 int ret;
7142 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7143 hdd_context_t *pHddCtx;
7144
7145 if (NULL == pAdapter)
7146 {
7147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7148 "%s: HDD adapter is Null", __func__);
7149 return ;
7150 }
7151
7152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7153 if (NULL == pHddCtx)
7154 {
7155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7156 "%s: HDD context is Null!!!", __func__);
7157 return ;
7158 }
7159
7160 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7161
7162 if (0 > ret)
7163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7164
7165 cfg80211_sched_scan_results(pHddCtx->wiphy);
7166}
7167
7168/*
7169 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7170 * NL interface to enable PNO
7171 */
7172static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7173 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7174{
7175 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7176 tpSirPNOScanReq pPnoRequest = NULL;
7177 hdd_context_t *pHddCtx;
7178 tHalHandle hHal;
7179 v_U32_t i, indx, num_ch;
7180 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7181 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7182 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7183 eHalStatus status = eHAL_STATUS_FAILURE;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307184 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307185
7186 if (NULL == pAdapter)
7187 {
7188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7189 "%s: HDD adapter is Null", __func__);
7190 return -ENODEV;
7191 }
7192
7193 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307194 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307195
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307196 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307197 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7199 "%s: HDD context is not valid", __func__);
7200 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307201 }
7202
7203 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7204 if (NULL == hHal)
7205 {
7206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7207 "%s: HAL context is Null!!!", __func__);
7208 return -EAGAIN;
7209 }
7210
7211 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7212 if (NULL == pPnoRequest)
7213 {
7214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7215 "%s: vos_mem_malloc failed", __func__);
7216 return -ENODEV;
7217 }
7218
7219 pPnoRequest->enable = 1; /*Enable PNO */
7220 pPnoRequest->ucNetworksCount = request->n_match_sets;
7221
7222 if (( !pPnoRequest->ucNetworksCount ) ||
7223 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7224 {
7225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7226 "Network input is not correct");
7227 goto error;
7228 }
7229
7230 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7231 {
7232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7233 "Incorrect number of channels");
7234 goto error;
7235 }
7236
7237 /* Framework provides one set of channels(all)
7238 * common for all saved profile */
7239 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7240 channels_allowed, &num_channels_allowed))
7241 {
7242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7243 "%s: failed to get valid channel list", __func__);
7244 goto error;
7245 }
7246 /* Checking each channel against allowed channel list */
7247 num_ch = 0;
7248 for (i = 0; i < request->n_channels; i++)
7249 {
7250 for (indx = 0; indx < num_channels_allowed; indx++)
7251 {
7252 if (request->channels[i]->hw_value == channels_allowed[indx])
7253 {
7254 valid_ch[num_ch++] = request->channels[i]->hw_value;
7255 break ;
7256 }
7257 }
7258 }
7259
7260 /* Filling per profile params */
7261 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7262 {
7263 pPnoRequest->aNetworks[i].ssId.length =
7264 request->match_sets[i].ssid.ssid_len;
7265
7266 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7267 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7268 {
7269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7270 "SSID Len %d is not correct for network %d",
7271 pPnoRequest->aNetworks[i].ssId.length, i);
7272 goto error;
7273 }
7274
7275 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7276 request->match_sets[i].ssid.ssid,
7277 request->match_sets[i].ssid.ssid_len);
7278 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7279 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7280 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7281
7282 /*Copying list of valid channel into request */
7283 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7284 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7285
7286 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7287 }
7288
7289 /* framework provides interval in ms */
7290 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7291 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7292 (request->interval)/1000;
7293 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7294 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7295
7296 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7297 pPnoRequest, pAdapter->sessionId,
7298 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7299 if (eHAL_STATUS_SUCCESS != status)
7300 {
7301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7302 "Failed to enable PNO");
7303 goto error;
7304 }
7305
7306error:
7307 vos_mem_free(pPnoRequest);
7308 return status;
7309}
7310
7311/*
7312 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7313 * NL interface to disable PNO
7314 */
7315static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7316 struct net_device *dev)
7317{
7318 eHalStatus status = eHAL_STATUS_FAILURE;
7319 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7320 hdd_context_t *pHddCtx;
7321 tHalHandle hHal;
7322 tpSirPNOScanReq pPnoRequest = NULL;
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307323 int result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307324
7325 ENTER();
7326
7327 if (NULL == pAdapter)
7328 {
7329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7330 "%s: HDD adapter is Null", __func__);
7331 return -ENODEV;
7332 }
7333
7334 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307335 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307336
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307337 if (0 != result)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307338 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7340 "%s: HDD context is not valid", __func__);
7341 return result;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307342 }
7343
7344 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7345 if (NULL == hHal)
7346 {
7347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7348 "%s: HAL context is Null!!!", __func__);
7349 return -EAGAIN;
7350 }
7351
7352 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7353 if (NULL == pPnoRequest)
7354 {
7355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7356 "%s: vos_mem_malloc failed", __func__);
7357 return -ENODEV;
7358 }
7359
7360 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7361 pPnoRequest->enable = 0; /* Disable PNO */
7362 pPnoRequest->ucNetworksCount = 0;
7363
7364 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7365 pAdapter->sessionId,
7366 NULL, pAdapter);
7367 if (eHAL_STATUS_SUCCESS != status)
7368 {
7369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7370 "Failed to disabled PNO");
7371 }
7372
7373 vos_mem_free(pPnoRequest);
7374
7375 EXIT();
7376 return status;
7377}
7378
7379#endif /*FEATURE_WLAN_SCAN_PNO*/
7380
7381
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007382#ifdef FEATURE_WLAN_TDLS
7383static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7384 u8 *peer, u8 action_code, u8 dialog_token,
7385 u16 status_code, const u8 *buf, size_t len)
7386{
7387
7388 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7389 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007390 u8 peerMac[6];
7391 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007392 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007393 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007394 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007395
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007396 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007397 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007399 "Invalid arguments");
7400 return -EINVAL;
7401 }
7402
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007403 if (pHddCtx->isLogpInProgress)
7404 {
7405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7406 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007407 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007408 return -EBUSY;
7409 }
7410
Hoonki Lee27511902013-03-14 18:19:06 -07007411 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007412 {
Hoonki Lee27511902013-03-14 18:19:06 -07007413 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7414 "%s: TDLS mode is disabled OR not enabled in FW."
7415 MAC_ADDRESS_STR " action %d declined.",
7416 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007417 return -ENOTSUPP;
7418 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007419
Hoonki Lee27511902013-03-14 18:19:06 -07007420 /* other than teardown frame, other mgmt frames are not sent if disabled */
7421 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7422 {
7423 /* if tdls_mode is disabled to respond to peer's request */
7424 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7425 {
7426 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7427 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007428 " TDLS mode is disabled. action %d declined.",
7429 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007430
7431 return -ENOTSUPP;
7432 }
7433 }
7434
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007435 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7436 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007437 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007438 {
7439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007440 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007441 " TDLS setup is ongoing. action %d declined.",
7442 __func__, MAC_ADDR_ARRAY(peer), action_code);
7443 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007444 }
7445 }
7446
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007447 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7448 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007449 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007450 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007451 {
7452 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7453 we return error code at 'add_station()'. Hence we have this
7454 check again in addtion to add_station().
7455 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007456 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007457 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7459 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007460 " TDLS Max peer already connected. action %d declined.",
7461 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007462 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007463 }
7464 else
7465 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007466 /* maximum reached. tweak to send error code to peer and return
7467 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007468 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7470 "%s: " MAC_ADDRESS_STR
7471 " TDLS Max peer already connected send response status %d",
7472 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007473 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007474 /* fall through to send setup resp with failure status
7475 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007476 }
7477 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007478 else
7479 {
7480 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007481 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007482 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007483 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007485 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7486 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007487 return -EPERM;
7488 }
7489 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007490 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007491 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007492
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007493#ifdef WLAN_FEATURE_TDLS_DEBUG
7494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007495 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7496 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7497 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007498#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007499
Hoonki Leea34dd892013-02-05 22:56:02 -08007500 /*Except teardown responder will not be used so just make 0*/
7501 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007502 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007503 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007504
7505 hddTdlsPeer_t *pTdlsPeer;
7506 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7507
7508 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7509 responder = pTdlsPeer->is_responder;
7510 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007511 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7513 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7514 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7515 dialog_token, status_code, len);
7516 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007517 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007518 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007519
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05307520 /* For explicit trigger of DIS_REQ come out of BMPS for
7521 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07007522 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05307523 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
7524 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07007525 {
7526 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7527 {
7528 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05307529 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07007530 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7531 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05307532 if (SIR_MAC_TDLS_DIS_REQ != action_code)
7533 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07007534 }
7535
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007536 /* make sure doesn't call send_mgmt() while it is pending */
7537 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7538 {
7539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7540 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7541 __func__, MAC_ADDR_ARRAY(peer), action_code);
7542 return -EBUSY;
7543 }
7544
7545 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007546 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7547
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007548 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007549 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007550
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007551 if (VOS_STATUS_SUCCESS != status)
7552 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7554 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007555 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007556 wlan_hdd_tdls_check_bmps(pAdapter);
7557 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007558 }
7559
Hoonki Leed37cbb32013-04-20 00:31:14 -07007560 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7561 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7562
7563 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007564 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7566 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7567 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007568 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007569 wlan_hdd_tdls_check_bmps(pAdapter);
7570 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007571 }
7572
Gopichand Nakkala05922802013-03-14 12:23:19 -07007573 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007574 {
7575 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007576 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007577 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007578
Hoonki Leea34dd892013-02-05 22:56:02 -08007579 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7580 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007581 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007582 }
7583 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7584 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007585 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007586 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007587
7588 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007589error:
7590 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7591 because we already know that this transaction will be failed,
7592 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7593 to be safe, do not change the state mahine.
7594 */
7595 if(max_sta_failed == 0 &&
7596 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7597 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7598 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007599}
7600
7601static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7602 u8 *peer, enum nl80211_tdls_operation oper)
7603{
7604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7605 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307606 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307607#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7608 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307609 tANI_U8 staIdx;
7610#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007611#ifdef WLAN_FEATURE_TDLS_DEBUG
7612 const char *tdls_oper_str[]= {
7613 "NL80211_TDLS_DISCOVERY_REQ",
7614 "NL80211_TDLS_SETUP",
7615 "NL80211_TDLS_TEARDOWN",
7616 "NL80211_TDLS_ENABLE_LINK",
7617 "NL80211_TDLS_DISABLE_LINK",
Gopichand Nakkala29d00192013-06-20 19:03:52 +05307618 "NL80211_TDLS_UNKNOWN_OPER"};
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007619#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007620 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007621
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307622 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007623 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007625 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007626 return -EINVAL;
7627 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007628
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307629 status = wlan_hdd_validate_context(pHddCtx);
7630
7631 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007632 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7634 "%s: HDD context is not valid", __func__);
7635 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007636 }
7637
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007638 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7639
7640 if ( NULL == pTdlsPeer ) {
7641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7642 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7643 return -EINVAL;
7644 }
7645
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007646#ifdef WLAN_FEATURE_TDLS_DEBUG
7647 if((int)oper > 4)
7648 oper = 5;
7649
7650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007651 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7652 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007653 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007654#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007655
7656 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007657 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007658 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007660 "TDLS Disabled in INI OR not enabled in FW. "
7661 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007662 return -ENOTSUPP;
7663 }
7664
7665 switch (oper) {
7666 case NL80211_TDLS_ENABLE_LINK:
7667 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007668 VOS_STATUS status;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307669 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007670
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007671 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7672 {
7673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7674 MAC_ADDRESS_STR " failed",
7675 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7676 return -EINVAL;
7677 }
7678
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007679 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007680 {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05307681 long ret;
7682
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307683 if (0 != wlan_hdd_tdls_get_link_establish_params(pAdapter, peer,&tdlsLinkEstablishParams)) {
7684 return -EINVAL;
7685 }
7686 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
7687
7688 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
7689 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
7690 /* Send TDLS peer UAPSD capabilities to the firmware and
7691 * register with the TL on after the response for this operation
7692 * is received .
7693 */
Gopichand Nakkala24be5312013-07-02 16:47:12 +05307694 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_link_establish_req_comp,
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307695 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Gopichand Nakkala24be5312013-07-02 16:47:12 +05307696 if (ret <= 0)
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307697 {
7698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7699 "%s: Link Establish Request Faled Status %ld",
Gopichand Nakkala24be5312013-07-02 16:47:12 +05307700 __func__, ret);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307701 return -EINVAL;
7702 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007703 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05307704 /* Mark TDLS client Authenticated .*/
7705 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
7706 pTdlsPeer->staId,
7707 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007708 if (VOS_STATUS_SUCCESS == status)
7709 {
Hoonki Lee14621352013-04-16 17:51:19 -07007710 if (pTdlsPeer->is_responder == 0)
7711 {
7712 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7713
7714 wlan_hdd_tdls_timer_restart(pAdapter,
7715 &pTdlsPeer->initiatorWaitTimeoutTimer,
7716 WAIT_TIME_TDLS_INITIATOR);
7717 /* suspend initiator TX until it receives direct packet from the
7718 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7719 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7720 &staId, NULL);
7721 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007722 wlan_hdd_tdls_increment_peer_count(pAdapter);
7723 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007724 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307725
7726 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05307727 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
7728 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307729 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05307730 int ac;
7731 uint8 ucAc[4] = { WLANTL_AC_VO,
7732 WLANTL_AC_VI,
7733 WLANTL_AC_BK,
7734 WLANTL_AC_BE };
7735 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
7736 for(ac=0; ac < 4; ac++)
7737 {
7738 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7739 pTdlsPeer->staId, ucAc[ac],
7740 tlTid[ac], tlTid[ac], 0, 0,
7741 WLANTL_BI_DIR );
7742 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307743 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007744 }
7745
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007746 }
7747 break;
7748 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007749 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007750 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007751 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007752 long status;
7753
7754 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7755
Lee Hoonkic1262f22013-01-24 21:59:00 -08007756 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7757 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007758
7759 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7760 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7761 if (status <= 0)
7762 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007763 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7765 "%s: Del station failed status %ld",
7766 __func__, status);
7767 return -EPERM;
7768 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007769 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007770 }
7771 else
7772 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7774 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007775 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307776#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7777 if (pHddTdlsCtx->defer_link_lost_indication)
7778 {
7779 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7780 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7781 {
7782 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7783 if ( 0 != status)
7784 {
7785 hddLog(VOS_TRACE_LEVEL_ERROR,
7786 "%s wlan_hdd_disconnect failure, returned %d \n",
7787 __func__, (int)status );
7788 return -EINVAL;
7789 }
7790 }
7791 }
7792#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007793 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007794 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007795 case NL80211_TDLS_TEARDOWN:
7796 case NL80211_TDLS_SETUP:
7797 case NL80211_TDLS_DISCOVERY_REQ:
7798 /* We don't support in-driver setup/teardown/discovery */
7799 return -ENOTSUPP;
7800 default:
7801 return -ENOTSUPP;
7802 }
7803 return 0;
7804}
Chilam NG571c65a2013-01-19 12:27:36 +05307805
7806int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7807 struct net_device *dev, u8 *peer)
7808{
7809 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7810 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7811
7812 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7813 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7814}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007815#endif
7816
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307817#ifdef WLAN_FEATURE_GTK_OFFLOAD
7818/*
7819 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7820 * Callback rountine called upon receiving response for
7821 * get offload info
7822 */
7823void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7824 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7825{
7826
7827 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307828 tANI_U8 tempReplayCounter[8];
7829 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307830
7831 ENTER();
7832
7833 if (NULL == pAdapter)
7834 {
7835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7836 "%s: HDD adapter is Null", __func__);
7837 return ;
7838 }
7839
7840 if (NULL == pGtkOffloadGetInfoRsp)
7841 {
7842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7843 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7844 return ;
7845 }
7846
7847 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7848 {
7849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7850 "%s: wlan Failed to get replay counter value",
7851 __func__);
7852 return ;
7853 }
7854
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307855 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7856 /* Update replay counter */
7857 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
7858 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
7859
7860 {
7861 /* changing from little to big endian since supplicant
7862 * works on big endian format
7863 */
7864 int i;
7865 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
7866
7867 for (i = 0; i < 8; i++)
7868 {
7869 tempReplayCounter[7-i] = (tANI_U8)p[i];
7870 }
7871 }
7872
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307873 /* Update replay counter to NL */
7874 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307875 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307876}
7877
7878/*
7879 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7880 * This function is used to offload GTK rekeying job to the firmware.
7881 */
7882int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7883 struct cfg80211_gtk_rekey_data *data)
7884{
7885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7886 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7887 hdd_station_ctx_t *pHddStaCtx;
7888 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307890 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307891 eHalStatus status = eHAL_STATUS_FAILURE;
7892
7893 ENTER();
7894
7895 if (NULL == pAdapter)
7896 {
7897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7898 "%s: HDD adapter is Null", __func__);
7899 return -ENODEV;
7900 }
7901
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307902 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307903
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307904 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307905 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7907 "%s: HDD context is not valid", __func__);
7908 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307909 }
7910
7911 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7912 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7913 if (NULL == hHal)
7914 {
7915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7916 "%s: HAL context is Null!!!", __func__);
7917 return -EAGAIN;
7918 }
7919
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307920 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
7921 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
7922 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
7923 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307924 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307925 {
7926 /* changing from big to little endian since driver
7927 * works on little endian format
7928 */
7929 tANI_U8 *p =
7930 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
7931 int i;
7932
7933 for (i = 0; i < 8; i++)
7934 {
7935 p[7-i] = data->replay_ctr[i];
7936 }
7937 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307938
7939 if (TRUE == pHddCtx->hdd_wlan_suspended)
7940 {
7941 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307942 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
7943 sizeof (tSirGtkOffloadParams));
7944 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307945 pAdapter->sessionId);
7946
7947 if (eHAL_STATUS_SUCCESS != status)
7948 {
7949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7950 "%s: sme_SetGTKOffload failed, returned %d",
7951 __func__, status);
7952 return status;
7953 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7955 "%s: sme_SetGTKOffload successfull", __func__);
7956 }
7957 else
7958 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7960 "%s: wlan not suspended GTKOffload request is stored",
7961 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307962 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05307963
7964 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307965}
7966#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7967
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307968/*
7969 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
7970 * This function is used to set access control policy
7971 */
7972static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
7973 struct net_device *dev, const struct cfg80211_acl_data *params)
7974{
7975 int i;
7976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7977 hdd_hostapd_state_t *pHostapdState;
7978 tsap_Config_t *pConfig;
7979 v_CONTEXT_t pVosContext = NULL;
7980 hdd_context_t *pHddCtx;
7981 int status;
7982
7983 ENTER();
7984
7985 if (NULL == pAdapter)
7986 {
7987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7988 "%s: HDD adapter is Null", __func__);
7989 return -ENODEV;
7990 }
7991
7992 if (NULL == params)
7993 {
7994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7995 "%s: params is Null", __func__);
7996 return -EINVAL;
7997 }
7998
7999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8000 status = wlan_hdd_validate_context(pHddCtx);
8001
8002 if (0 != status)
8003 {
8004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8005 "%s: HDD context is not valid", __func__);
8006 return status;
8007 }
8008
8009 pVosContext = pHddCtx->pvosContext;
8010 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8011
8012 if (NULL == pHostapdState)
8013 {
8014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8015 "%s: pHostapdState is Null", __func__);
8016 return -EINVAL;
8017 }
8018
8019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
8020 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
8021
8022 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
8023 {
8024 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
8025
8026 /* default value */
8027 pConfig->num_accept_mac = 0;
8028 pConfig->num_deny_mac = 0;
8029
8030 /**
8031 * access control policy
8032 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
8033 * listed in hostapd.deny file.
8034 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
8035 * listed in hostapd.accept file.
8036 */
8037 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
8038 {
8039 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
8040 }
8041 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
8042 {
8043 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
8044 }
8045 else
8046 {
8047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8048 "%s:Acl Policy : %d is not supported",
8049 __func__, params->acl_policy);
8050 return -ENOTSUPP;
8051 }
8052
8053 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
8054 {
8055 pConfig->num_accept_mac = params->n_acl_entries;
8056 for (i = 0; i < params->n_acl_entries; i++)
8057 {
8058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8059 "** Add ACL MAC entry %i in WhiletList :"
8060 MAC_ADDRESS_STR, i,
8061 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8062
8063 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
8064 sizeof(qcmacaddr));
8065 }
8066 }
8067 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
8068 {
8069 pConfig->num_deny_mac = params->n_acl_entries;
8070 for (i = 0; i < params->n_acl_entries; i++)
8071 {
8072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8073 "** Add ACL MAC entry %i in BlackList :"
8074 MAC_ADDRESS_STR, i,
8075 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
8076
8077 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
8078 sizeof(qcmacaddr));
8079 }
8080 }
8081
8082 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
8083 {
8084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8085 "%s: SAP Set Mac Acl fail", __func__);
8086 return -EINVAL;
8087 }
8088 }
8089 else
8090 {
8091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8092 "%s: Invalid device_mode = %d",
8093 __func__, pAdapter->device_mode);
8094 return -EINVAL;
8095 }
8096
8097 return 0;
8098}
8099
Leo Chang9056f462013-08-01 19:21:11 -07008100#ifdef WLAN_NL80211_TESTMODE
8101#ifdef FEATURE_WLAN_LPHB
8102static void wlan_hdd_cfg80211_lphb_wait_timeout_ind_handler
8103(
8104 void *pAdapter,
8105 void *indCont
8106)
8107{
8108 tSirLPHBTimeoutInd *lphbTimeoutInd;
8109 struct sk_buff *skb;
8110
8111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8112 "LPHB wait timeout indication arrived");
8113
8114 if (NULL == indCont)
8115 {
8116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8117 "LPHB timeout, invalid argument");
8118 return;
8119 }
8120
8121 lphbTimeoutInd = (tSirLPHBTimeoutInd *)indCont;
8122 skb = cfg80211_testmode_alloc_event_skb(
8123 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
8124 sizeof(tSirLPHBTimeoutInd),
8125 GFP_ATOMIC);
8126 if (!skb)
8127 {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "LPHB timeout, NL buffer alloc fail");
8130 return;
8131 }
8132
8133 NLA_PUT_U32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB);
8134 NLA_PUT_U32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbTimeoutInd->protocolType);
8135 NLA_PUT(skb, WLAN_HDD_TM_ATTR_DATA,
8136 sizeof(tSirLPHBTimeoutInd), lphbTimeoutInd);
8137 cfg80211_testmode_event(skb, GFP_ATOMIC);
8138 return;
8139
8140nla_put_failure:
8141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8142 "NLA Put fail");
8143 kfree_skb(skb);
8144
8145 return;
8146}
8147#endif /* FEATURE_WLAN_LPHB */
8148
8149static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
8150{
8151 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
8152 int err = 0;
8153#ifdef FEATURE_WLAN_LPHB
8154 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8155#endif /* FEATURE_WLAN_LPHB */
8156
8157 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
8158 if (err)
8159 {
8160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8161 "%s Testmode INV ATTR", __func__);
8162 return err;
8163 }
8164
8165 if (!tb[WLAN_HDD_TM_ATTR_CMD])
8166 {
8167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8168 "%s Testmode INV CMD", __func__);
8169 return -EINVAL;
8170 }
8171
8172 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
8173 {
8174#ifdef FEATURE_WLAN_LPHB
8175 /* Low Power Heartbeat configuration request */
8176 case WLAN_HDD_TM_CMD_WLAN_HB:
8177 {
8178 int buf_len;
8179 void *buf;
8180 tSirLPHBReq *hb_params = NULL;
8181
8182 if (!tb[WLAN_HDD_TM_ATTR_DATA])
8183 {
8184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8185 "%s Testmode INV DATA", __func__);
8186 return -EINVAL;
8187 }
8188
8189 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
8190 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
8191 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
8192 if (NULL == hb_params)
8193 {
8194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8195 "%s Request Buffer Alloc Fail", __func__);
8196 return -EINVAL;
8197 }
8198
8199 vos_mem_copy(hb_params, buf, buf_len);
8200
8201 /* LPHB enable and disable request will send to FW
8202 * when host suspend and resume
8203 * host suspend -> enable LPHB
8204 * host resume -> disable LPHB
8205 * if host is not suspend, cache into HDD context
8206 * and when host goes to suspend, send request to FW */
8207 if ((LPHB_SET_EN_PARAMS_INDID == hb_params->cmd) &&
8208 (!pHddCtx->hdd_wlan_suspended))
8209 {
8210 /* Feature enable command cache into HDD context,
8211 * if WLAN is not suspend
8212 * When WLAN goes into suspend, send enable command to FW */
8213 pHddCtx->lphbEnableReq.enable =
8214 hb_params->params.lphbEnableReq.enable;
8215 pHddCtx->lphbEnableReq.item =
8216 hb_params->params.lphbEnableReq.item;
8217 pHddCtx->lphbEnableReq.session =
8218 hb_params->params.lphbEnableReq.session;
8219 vos_mem_free(hb_params);
8220 }
8221 else
8222 {
8223 eHalStatus smeStatus;
8224
8225 /* If WLAN is suspend state, send enable command immediately */
8226 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
8227 hb_params,
8228 wlan_hdd_cfg80211_lphb_wait_timeout_ind_handler);
8229 if (eHAL_STATUS_SUCCESS != smeStatus)
8230 {
8231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8232 "LPHB Config Fail, disable");
8233 pHddCtx->lphbEnableReq.enable = 0;
8234 vos_mem_free(hb_params);
8235 }
8236 }
8237 return 0;
8238 }
8239#endif /* FEATURE_WLAN_LPHB */
8240 default:
8241 return -EOPNOTSUPP;
8242 }
8243
8244 return err;
8245}
8246#endif /* CONFIG_NL80211_TESTMODE */
8247
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308248static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
8249 struct net_device *dev,
8250 int idx, struct survey_info *survey)
8251{
8252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8253 hdd_context_t *pHddCtx;
8254 tHalHandle halHandle;
8255 v_U32_t channel, freq;
8256 v_S7_t snr,rssi;
8257 int status, i, j, filled = 0;
8258
8259 ENTER();
8260
8261
8262 if (NULL == pAdapter)
8263 {
8264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8265 "%s: HDD adapter is Null", __func__);
8266 return -ENODEV;
8267 }
8268
8269 if (NULL == wiphy)
8270 {
8271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8272 "%s: wiphy is Null", __func__);
8273 return -ENODEV;
8274 }
8275
8276 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8277 status = wlan_hdd_validate_context(pHddCtx);
8278
8279 if (0 != status)
8280 {
8281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8282 "%s: HDD context is not valid", __func__);
8283 return status;
8284 }
8285
8286 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
8287 0 != pAdapter->survey_idx)
8288 {
8289 /* The survey dump ops when implemented completely is expected to
8290 * return a survey of all channels and the ops is called by the
8291 * kernel with incremental values of the argument 'idx' till it
8292 * returns -ENONET. But we can only support the survey for the
8293 * operating channel for now. survey_idx is used to track
8294 * that the ops is called only once and then return -ENONET for
8295 * the next iteration
8296 */
8297 pAdapter->survey_idx = 0;
8298 return -ENONET;
8299 }
8300
8301 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8302
8303 wlan_hdd_get_snr(pAdapter, &snr);
8304 wlan_hdd_get_rssi(pAdapter, &rssi);
8305
8306 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
8307 hdd_wlan_get_freq(channel, &freq);
8308
8309
8310 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8311 {
8312 if (NULL == wiphy->bands[i])
8313 {
8314 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
8315 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
8316 continue;
8317 }
8318
8319 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8320 {
8321 struct ieee80211_supported_band *band = wiphy->bands[i];
8322
8323 if (band->channels[j].center_freq == (v_U16_t)freq)
8324 {
8325 survey->channel = &band->channels[j];
8326 /* The Rx BDs contain SNR values in dB for the received frames
8327 * while the supplicant expects noise. So we calculate and
8328 * return the value of noise (dBm)
8329 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
8330 */
8331 survey->noise = rssi - snr;
8332 survey->filled = SURVEY_INFO_NOISE_DBM;
8333 filled = 1;
8334 }
8335 }
8336 }
8337
8338 if (filled)
8339 pAdapter->survey_idx = 1;
8340 else
8341 {
8342 pAdapter->survey_idx = 0;
8343 return -ENONET;
8344 }
8345
8346 return 0;
8347}
8348
Jeff Johnson295189b2012-06-20 16:38:30 -07008349/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308350static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07008351{
8352 .add_virtual_intf = wlan_hdd_add_virtual_intf,
8353 .del_virtual_intf = wlan_hdd_del_virtual_intf,
8354 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
8355 .change_station = wlan_hdd_change_station,
8356#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8357 .add_beacon = wlan_hdd_cfg80211_add_beacon,
8358 .del_beacon = wlan_hdd_cfg80211_del_beacon,
8359 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008360#else
8361 .start_ap = wlan_hdd_cfg80211_start_ap,
8362 .change_beacon = wlan_hdd_cfg80211_change_beacon,
8363 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07008364#endif
8365 .change_bss = wlan_hdd_cfg80211_change_bss,
8366 .add_key = wlan_hdd_cfg80211_add_key,
8367 .get_key = wlan_hdd_cfg80211_get_key,
8368 .del_key = wlan_hdd_cfg80211_del_key,
8369 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008370#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 .scan = wlan_hdd_cfg80211_scan,
8374 .connect = wlan_hdd_cfg80211_connect,
8375 .disconnect = wlan_hdd_cfg80211_disconnect,
8376 .join_ibss = wlan_hdd_cfg80211_join_ibss,
8377 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
8378 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
8379 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
8380 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
8382 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
8383 .mgmt_tx = wlan_hdd_action,
8384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8385 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
8386 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
8387 .set_txq_params = wlan_hdd_set_txq_params,
8388#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 .get_station = wlan_hdd_cfg80211_get_station,
8390 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
8391 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008392 .add_station = wlan_hdd_cfg80211_add_station,
8393#ifdef FEATURE_WLAN_LFR
8394 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
8395 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
8396 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
8397#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008398#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
8399 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
8400#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008401#ifdef FEATURE_WLAN_TDLS
8402 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
8403 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
8404#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308405#ifdef WLAN_FEATURE_GTK_OFFLOAD
8406 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
8407#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308408#ifdef FEATURE_WLAN_SCAN_PNO
8409 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
8410 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
8411#endif /*FEATURE_WLAN_SCAN_PNO */
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308412 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07008413#ifdef WLAN_NL80211_TESTMODE
8414 .testmode_cmd = wlan_hdd_cfg80211_testmode,
8415#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308416 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008417};
8418