blob: 56a027fc8c762f968664b4695cff063c9208b9c9 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 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 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Kiet Lamaa8e15a2014-02-11 23:30:06 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/**========================================================================
32
33 \file wlan_hdd_cfg80211.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037 ========================================================================*/
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070040
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070041 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070042
43
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070044 This section contains comments describing changes made to the module.
45 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070046
47
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070052 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070053 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070056 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070057 ==========================================================================*/
58
Jeff Johnson295189b2012-06-20 16:38:30 -070059
60#include <linux/version.h>
61#include <linux/module.h>
62#include <linux/kernel.h>
63#include <linux/init.h>
64#include <linux/wireless.h>
65#include <wlan_hdd_includes.h>
66#include <net/arp.h>
67#include <net/cfg80211.h>
68#include <linux/wireless.h>
69#include <wlan_hdd_wowl.h>
70#include <aniGlobal.h>
71#include "ccmApi.h"
72#include "sirParams.h"
73#include "dot11f.h"
74#include "wlan_hdd_assoc.h"
75#include "wlan_hdd_wext.h"
76#include "sme_Api.h"
77#include "wlan_hdd_p2p.h"
78#include "wlan_hdd_cfg80211.h"
79#include "wlan_hdd_hostapd.h"
80#include "sapInternal.h"
81#include "wlan_hdd_softap_tx_rx.h"
82#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053083#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053084#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053085#include "wlan_hdd_trace.h"
86#include "vos_types.h"
87#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088#ifdef WLAN_BTAMP_FEATURE
89#include "bap_hdd_misc.h"
90#endif
91#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#ifdef FEATURE_WLAN_TDLS
93#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080096#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099
100#define g_mode_rates_size (12)
101#define a_mode_rates_size (8)
102#define FREQ_BASE_80211G (2407)
103#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700104#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530105#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800107 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109#define HDD2GHZCHAN(freq, chan, flag) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (freq), \
112 .hw_value = (chan),\
113 .flags = (flag), \
114 .max_antenna_gain = 0 ,\
115 .max_power = 30, \
116}
117
118#define HDD5GHZCHAN(freq, chan, flag) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = (freq), \
121 .hw_value = (chan),\
122 .flags = (flag), \
123 .max_antenna_gain = 0 ,\
124 .max_power = 30, \
125}
126
127#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
128{\
129 .bitrate = rate, \
130 .hw_value = rate_id, \
131 .flags = flag, \
132}
133
Lee Hoonkic1262f22013-01-24 21:59:00 -0800134#ifndef WLAN_FEATURE_TDLS_DEBUG
135#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
136#else
137#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
138#endif
139
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530140#ifdef WLAN_FEATURE_VOWIFI_11R
141#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
142#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
143#endif
144
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145#define HDD_CHANNEL_14 14
Dasari Srinivasbee4dce2014-10-28 17:09:42 +0530146#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530147
Sunil Duttc69bccb2014-05-26 21:30:20 +0530148#ifdef WLAN_FEATURE_LINK_LAYER_STATS
149/*
150 * Used to allocate the size of 4096 for the link layer stats.
151 * The size of 4096 is considered assuming that all data per
152 * respective event fit with in the limit.Please take a call
153 * on the limit based on the data requirements on link layer
154 * statistics.
155 */
156#define LL_STATS_EVENT_BUF_SIZE 4096
157#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530158#ifdef WLAN_FEATURE_EXTSCAN
159/*
160 * Used to allocate the size of 4096 for the EXTScan NL data.
161 * The size of 4096 is considered assuming that all data per
162 * respective event fit with in the limit.Please take a call
163 * on the limit based on the data requirements.
164 */
165
166#define EXTSCAN_EVENT_BUF_SIZE 4096
167#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
168#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530169
Atul Mittal115287b2014-07-08 13:26:33 +0530170/*EXT TDLS*/
171/*
172 * Used to allocate the size of 4096 for the TDLS.
173 * The size of 4096 is considered assuming that all data per
174 * respective event fit with in the limit.Please take a call
175 * on the limit based on the data requirements on link layer
176 * statistics.
177 */
178#define EXTTDLS_EVENT_BUF_SIZE 4096
179
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530180static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700181{
182 WLAN_CIPHER_SUITE_WEP40,
183 WLAN_CIPHER_SUITE_WEP104,
184 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800185#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700186#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
187 WLAN_CIPHER_SUITE_KRK,
188 WLAN_CIPHER_SUITE_CCMP,
189#else
190 WLAN_CIPHER_SUITE_CCMP,
191#endif
192#ifdef FEATURE_WLAN_WAPI
193 WLAN_CIPHER_SUITE_SMS4,
194#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700195#ifdef WLAN_FEATURE_11W
196 WLAN_CIPHER_SUITE_AES_CMAC,
197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700198};
199
200static inline int is_broadcast_ether_addr(const u8 *addr)
201{
202 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
203 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
204}
205
206static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530207{
Jeff Johnson295189b2012-06-20 16:38:30 -0700208 HDD2GHZCHAN(2412, 1, 0) ,
209 HDD2GHZCHAN(2417, 2, 0) ,
210 HDD2GHZCHAN(2422, 3, 0) ,
211 HDD2GHZCHAN(2427, 4, 0) ,
212 HDD2GHZCHAN(2432, 5, 0) ,
213 HDD2GHZCHAN(2437, 6, 0) ,
214 HDD2GHZCHAN(2442, 7, 0) ,
215 HDD2GHZCHAN(2447, 8, 0) ,
216 HDD2GHZCHAN(2452, 9, 0) ,
217 HDD2GHZCHAN(2457, 10, 0) ,
218 HDD2GHZCHAN(2462, 11, 0) ,
219 HDD2GHZCHAN(2467, 12, 0) ,
220 HDD2GHZCHAN(2472, 13, 0) ,
221 HDD2GHZCHAN(2484, 14, 0) ,
222};
223
Jeff Johnson295189b2012-06-20 16:38:30 -0700224static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
225{
226 HDD2GHZCHAN(2412, 1, 0) ,
227 HDD2GHZCHAN(2437, 6, 0) ,
228 HDD2GHZCHAN(2462, 11, 0) ,
229};
Jeff Johnson295189b2012-06-20 16:38:30 -0700230
231static struct ieee80211_channel hdd_channels_5_GHZ[] =
232{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700233 HDD5GHZCHAN(4920, 240, 0) ,
234 HDD5GHZCHAN(4940, 244, 0) ,
235 HDD5GHZCHAN(4960, 248, 0) ,
236 HDD5GHZCHAN(4980, 252, 0) ,
237 HDD5GHZCHAN(5040, 208, 0) ,
238 HDD5GHZCHAN(5060, 212, 0) ,
239 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700240 HDD5GHZCHAN(5180, 36, 0) ,
241 HDD5GHZCHAN(5200, 40, 0) ,
242 HDD5GHZCHAN(5220, 44, 0) ,
243 HDD5GHZCHAN(5240, 48, 0) ,
244 HDD5GHZCHAN(5260, 52, 0) ,
245 HDD5GHZCHAN(5280, 56, 0) ,
246 HDD5GHZCHAN(5300, 60, 0) ,
247 HDD5GHZCHAN(5320, 64, 0) ,
248 HDD5GHZCHAN(5500,100, 0) ,
249 HDD5GHZCHAN(5520,104, 0) ,
250 HDD5GHZCHAN(5540,108, 0) ,
251 HDD5GHZCHAN(5560,112, 0) ,
252 HDD5GHZCHAN(5580,116, 0) ,
253 HDD5GHZCHAN(5600,120, 0) ,
254 HDD5GHZCHAN(5620,124, 0) ,
255 HDD5GHZCHAN(5640,128, 0) ,
256 HDD5GHZCHAN(5660,132, 0) ,
257 HDD5GHZCHAN(5680,136, 0) ,
258 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800259#ifdef FEATURE_WLAN_CH144
260 HDD5GHZCHAN(5720,144, 0) ,
261#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 HDD5GHZCHAN(5745,149, 0) ,
263 HDD5GHZCHAN(5765,153, 0) ,
264 HDD5GHZCHAN(5785,157, 0) ,
265 HDD5GHZCHAN(5805,161, 0) ,
266 HDD5GHZCHAN(5825,165, 0) ,
267};
268
269static struct ieee80211_rate g_mode_rates[] =
270{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530271 HDD_G_MODE_RATETAB(10, 0x1, 0),
272 HDD_G_MODE_RATETAB(20, 0x2, 0),
273 HDD_G_MODE_RATETAB(55, 0x4, 0),
274 HDD_G_MODE_RATETAB(110, 0x8, 0),
275 HDD_G_MODE_RATETAB(60, 0x10, 0),
276 HDD_G_MODE_RATETAB(90, 0x20, 0),
277 HDD_G_MODE_RATETAB(120, 0x40, 0),
278 HDD_G_MODE_RATETAB(180, 0x80, 0),
279 HDD_G_MODE_RATETAB(240, 0x100, 0),
280 HDD_G_MODE_RATETAB(360, 0x200, 0),
281 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_rate a_mode_rates[] =
286{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287 HDD_G_MODE_RATETAB(60, 0x10, 0),
288 HDD_G_MODE_RATETAB(90, 0x20, 0),
289 HDD_G_MODE_RATETAB(120, 0x40, 0),
290 HDD_G_MODE_RATETAB(180, 0x80, 0),
291 HDD_G_MODE_RATETAB(240, 0x100, 0),
292 HDD_G_MODE_RATETAB(360, 0x200, 0),
293 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 HDD_G_MODE_RATETAB(540, 0x800, 0),
295};
296
297static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
298{
299 .channels = hdd_channels_2_4_GHZ,
300 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
301 .band = IEEE80211_BAND_2GHZ,
302 .bitrates = g_mode_rates,
303 .n_bitrates = g_mode_rates_size,
304 .ht_cap.ht_supported = 1,
305 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
306 | IEEE80211_HT_CAP_GRN_FLD
307 | IEEE80211_HT_CAP_DSSSCCK40
308 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
314};
315
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
317{
318 .channels = hdd_social_channels_2_4_GHZ,
319 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
320 .band = IEEE80211_BAND_2GHZ,
321 .bitrates = g_mode_rates,
322 .n_bitrates = g_mode_rates_size,
323 .ht_cap.ht_supported = 1,
324 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
325 | IEEE80211_HT_CAP_GRN_FLD
326 | IEEE80211_HT_CAP_DSSSCCK40
327 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
328 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
329 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
330 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
331 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
332 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
333};
Jeff Johnson295189b2012-06-20 16:38:30 -0700334
335static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
336{
337 .channels = hdd_channels_5_GHZ,
338 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
339 .band = IEEE80211_BAND_5GHZ,
340 .bitrates = a_mode_rates,
341 .n_bitrates = a_mode_rates_size,
342 .ht_cap.ht_supported = 1,
343 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
344 | IEEE80211_HT_CAP_GRN_FLD
345 | IEEE80211_HT_CAP_DSSSCCK40
346 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
347 | IEEE80211_HT_CAP_SGI_40
348 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
349 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
350 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
351 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
352 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
353 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
354};
355
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530356/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 TX/RX direction for each kind of interface */
358static const struct ieee80211_txrx_stypes
359wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
360 [NL80211_IFTYPE_STATION] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ACTION) |
363 BIT(SIR_MAC_MGMT_PROBE_REQ),
364 },
365 [NL80211_IFTYPE_AP] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
368 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
369 BIT(SIR_MAC_MGMT_PROBE_REQ) |
370 BIT(SIR_MAC_MGMT_DISASSOC) |
371 BIT(SIR_MAC_MGMT_AUTH) |
372 BIT(SIR_MAC_MGMT_DEAUTH) |
373 BIT(SIR_MAC_MGMT_ACTION),
374 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700375 [NL80211_IFTYPE_ADHOC] = {
376 .tx = 0xffff,
377 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
378 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_PROBE_REQ) |
380 BIT(SIR_MAC_MGMT_DISASSOC) |
381 BIT(SIR_MAC_MGMT_AUTH) |
382 BIT(SIR_MAC_MGMT_DEAUTH) |
383 BIT(SIR_MAC_MGMT_ACTION),
384 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 [NL80211_IFTYPE_P2P_CLIENT] = {
386 .tx = 0xffff,
387 .rx = BIT(SIR_MAC_MGMT_ACTION) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ),
389 },
390 [NL80211_IFTYPE_P2P_GO] = {
391 /* This is also same as for SoftAP */
392 .tx = 0xffff,
393 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
394 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
395 BIT(SIR_MAC_MGMT_PROBE_REQ) |
396 BIT(SIR_MAC_MGMT_DISASSOC) |
397 BIT(SIR_MAC_MGMT_AUTH) |
398 BIT(SIR_MAC_MGMT_DEAUTH) |
399 BIT(SIR_MAC_MGMT_ACTION),
400 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700401};
402
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800403#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404static const struct ieee80211_iface_limit
405wlan_hdd_iface_limit[] = {
406 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800407 /* max = 3 ; Our driver create two interfaces during driver init
408 * wlan0 and p2p0 interfaces. p2p0 is considered as station
409 * interface until a group is formed. In JB architecture, once the
410 * group is formed, interface type of p2p0 is changed to P2P GO or
411 * Client.
412 * When supplicant remove the group, it first issue a set interface
413 * cmd to change the mode back to Station. In JB this works fine as
414 * we advertize two station type interface during driver init.
415 * Some vendors create separate interface for P2P GO/Client,
416 * after group formation(Third one). But while group remove
417 * supplicant first tries to change the mode(3rd interface) to STATION
418 * But as we advertized only two sta type interfaces nl80211 was
419 * returning error for the third one which was leading to failure in
420 * delete interface. Ideally while removing the group, supplicant
421 * should not try to change the 3rd interface mode to Station type.
422 * Till we get a fix in wpa_supplicant, we advertize max STA
423 * interface type to 3
424 */
425 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800426 .types = BIT(NL80211_IFTYPE_STATION),
427 },
428 {
429 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700430 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800431 },
432 {
433 .max = 1,
434 .types = BIT(NL80211_IFTYPE_P2P_GO) |
435 BIT(NL80211_IFTYPE_P2P_CLIENT),
436 },
437};
438
439/* By default, only single channel concurrency is allowed */
440static struct ieee80211_iface_combination
441wlan_hdd_iface_combination = {
442 .limits = wlan_hdd_iface_limit,
443 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800444 /*
445 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
446 * and p2p0 interfaces during driver init
447 * Some vendors create separate interface for P2P operations.
448 * wlan0: STA interface
449 * p2p0: P2P Device interface, action frames goes
450 * through this interface.
451 * p2p-xx: P2P interface, After GO negotiation this interface is
452 * created for p2p operations(GO/CLIENT interface).
453 */
454 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
456 .beacon_int_infra_match = false,
457};
458#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459
Jeff Johnson295189b2012-06-20 16:38:30 -0700460static struct cfg80211_ops wlan_hdd_cfg80211_ops;
461
462/* Data rate 100KBPS based on IE Index */
463struct index_data_rate_type
464{
465 v_U8_t beacon_rate_index;
466 v_U16_t supported_rate[4];
467};
468
469/* 11B, 11G Rate table include Basic rate and Extended rate
470 The IDX field is the rate index
471 The HI field is the rate when RSSI is strong or being ignored
472 (in this case we report actual rate)
473 The MID field is the rate when RSSI is moderate
474 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
475 The LO field is the rate when RSSI is low
476 (in this case we don't report rates, actual current rate used)
477 */
478static const struct
479{
480 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700481 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700482} supported_data_rate[] =
483{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700484/* IDX HI HM LM LO (RSSI-based index */
485 {2, { 10, 10, 10, 0}},
486 {4, { 20, 20, 10, 0}},
487 {11, { 55, 20, 10, 0}},
488 {12, { 60, 55, 20, 0}},
489 {18, { 90, 55, 20, 0}},
490 {22, {110, 55, 20, 0}},
491 {24, {120, 90, 60, 0}},
492 {36, {180, 120, 60, 0}},
493 {44, {220, 180, 60, 0}},
494 {48, {240, 180, 90, 0}},
495 {66, {330, 180, 90, 0}},
496 {72, {360, 240, 90, 0}},
497 {96, {480, 240, 120, 0}},
498 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700499};
500
501/* MCS Based rate table */
502static struct index_data_rate_type supported_mcs_rate[] =
503{
504/* MCS L20 L40 S20 S40 */
505 {0, {65, 135, 72, 150}},
506 {1, {130, 270, 144, 300}},
507 {2, {195, 405, 217, 450}},
508 {3, {260, 540, 289, 600}},
509 {4, {390, 810, 433, 900}},
510 {5, {520, 1080, 578, 1200}},
511 {6, {585, 1215, 650, 1350}},
512 {7, {650, 1350, 722, 1500}}
513};
514
Leo Chang6f8870f2013-03-26 18:11:36 -0700515#ifdef WLAN_FEATURE_11AC
516
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530517#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700518
519struct index_vht_data_rate_type
520{
521 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530522 v_U16_t supported_VHT80_rate[2];
523 v_U16_t supported_VHT40_rate[2];
524 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700525};
526
527typedef enum
528{
529 DATA_RATE_11AC_MAX_MCS_7,
530 DATA_RATE_11AC_MAX_MCS_8,
531 DATA_RATE_11AC_MAX_MCS_9,
532 DATA_RATE_11AC_MAX_MCS_NA
533} eDataRate11ACMaxMcs;
534
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530535/* SSID broadcast type */
536typedef enum eSSIDBcastType
537{
538 eBCAST_UNKNOWN = 0,
539 eBCAST_NORMAL = 1,
540 eBCAST_HIDDEN = 2,
541} tSSIDBcastType;
542
Leo Chang6f8870f2013-03-26 18:11:36 -0700543/* MCS Based VHT rate table */
544static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
545{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530546/* MCS L80 S80 L40 S40 L20 S40*/
547 {0, {293, 325}, {135, 150}, {65, 72}},
548 {1, {585, 650}, {270, 300}, {130, 144}},
549 {2, {878, 975}, {405, 450}, {195, 217}},
550 {3, {1170, 1300}, {540, 600}, {260, 289}},
551 {4, {1755, 1950}, {810, 900}, {390, 433}},
552 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
553 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
554 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
555 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
556 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700557};
558#endif /* WLAN_FEATURE_11AC */
559
c_hpothu79aab322014-07-14 21:11:01 +0530560/*array index points to MCS and array value points respective rssi*/
561static int rssiMcsTbl[][10] =
562{
563/*MCS 0 1 2 3 4 5 6 7 8 9*/
564 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
565 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
566 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
567};
568
Jeff Johnson295189b2012-06-20 16:38:30 -0700569extern struct net_device_ops net_ops_struct;
Dasari Srinivasf70e8fc2014-09-26 17:50:57 +0530570#ifdef FEATURE_WLAN_SCAN_PNO
571static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700573
Leo Chang9056f462013-08-01 19:21:11 -0700574#ifdef WLAN_NL80211_TESTMODE
575enum wlan_hdd_tm_attr
576{
577 WLAN_HDD_TM_ATTR_INVALID = 0,
578 WLAN_HDD_TM_ATTR_CMD = 1,
579 WLAN_HDD_TM_ATTR_DATA = 2,
580 WLAN_HDD_TM_ATTR_TYPE = 3,
581 /* keep last */
582 WLAN_HDD_TM_ATTR_AFTER_LAST,
583 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
584};
585
586enum wlan_hdd_tm_cmd
587{
588 WLAN_HDD_TM_CMD_WLAN_HB = 1,
589};
590
591#define WLAN_HDD_TM_DATA_MAX_LEN 5000
592
593static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
594{
595 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
596 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
597 .len = WLAN_HDD_TM_DATA_MAX_LEN },
598};
599#endif /* WLAN_NL80211_TESTMODE */
600
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800601#ifdef FEATURE_WLAN_CH_AVOID
602/*
603 * FUNCTION: wlan_hdd_send_avoid_freq_event
604 * This is called when wlan driver needs to send vendor specific
605 * avoid frequency range event to userspace
606 */
607int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
608 tHddAvoidFreqList *pAvoidFreqList)
609{
610 struct sk_buff *vendor_event;
611
612 ENTER();
613
614 if (!pHddCtx)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: HDD context is null", __func__);
618 return -1;
619 }
620
621 if (!pAvoidFreqList)
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
624 "%s: pAvoidFreqList is null", __func__);
625 return -1;
626 }
627
628 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
629 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530630 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800631 GFP_KERNEL);
632 if (!vendor_event)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "%s: cfg80211_vendor_event_alloc failed", __func__);
636 return -1;
637 }
638
639 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
640 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
641
642 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
643
644 EXIT();
645 return 0;
646}
647#endif /* FEATURE_WLAN_CH_AVOID */
648
Sunil Duttc69bccb2014-05-26 21:30:20 +0530649#ifdef WLAN_FEATURE_LINK_LAYER_STATS
650
651static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
652 struct sk_buff *vendor_event)
653{
654 if (nla_put_u8(vendor_event,
655 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
656 stats->rate.preamble) ||
657 nla_put_u8(vendor_event,
658 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
659 stats->rate.nss) ||
660 nla_put_u8(vendor_event,
661 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
662 stats->rate.bw) ||
663 nla_put_u8(vendor_event,
664 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
665 stats->rate.rateMcsIdx) ||
666 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
667 stats->rate.bitrate ) ||
668 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
669 stats->txMpdu ) ||
670 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
671 stats->rxMpdu ) ||
672 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
673 stats->mpduLost ) ||
674 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
675 stats->retries) ||
676 nla_put_u32(vendor_event,
677 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
678 stats->retriesShort ) ||
679 nla_put_u32(vendor_event,
680 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
681 stats->retriesLong))
682 {
683 hddLog(VOS_TRACE_LEVEL_ERROR,
684 FL("QCA_WLAN_VENDOR_ATTR put fail"));
685 return FALSE;
686 }
687 return TRUE;
688}
689
690static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
691 struct sk_buff *vendor_event)
692{
693 u32 i = 0;
694 struct nlattr *rateInfo;
695 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
696 stats->type) ||
697 nla_put(vendor_event,
698 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
699 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
700 nla_put_u32(vendor_event,
701 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
702 stats->capabilities) ||
703 nla_put_u32(vendor_event,
704 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
705 stats->numRate))
706 {
707 hddLog(VOS_TRACE_LEVEL_ERROR,
708 FL("QCA_WLAN_VENDOR_ATTR put fail"));
709 goto error;
710 }
711
712 rateInfo = nla_nest_start(vendor_event,
713 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
714 for (i = 0; i < stats->numRate; i++)
715 {
716 struct nlattr *rates;
717 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
718 stats->rateStats +
719 (i * sizeof(tSirWifiRateStat)));
720 rates = nla_nest_start(vendor_event, i);
721
722 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
723 {
724 hddLog(VOS_TRACE_LEVEL_ERROR,
725 FL("QCA_WLAN_VENDOR_ATTR put fail"));
726 return FALSE;
727 }
728 nla_nest_end(vendor_event, rates);
729 }
730 nla_nest_end(vendor_event, rateInfo);
731
732 return TRUE;
733error:
734 return FALSE;
735}
736
737static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
738 struct sk_buff *vendor_event)
739{
740 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
741 stats->ac ) ||
742 nla_put_u32(vendor_event,
743 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
744 stats->txMpdu ) ||
745 nla_put_u32(vendor_event,
746 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
747 stats->rxMpdu ) ||
748 nla_put_u32(vendor_event,
749 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
750 stats->txMcast ) ||
751 nla_put_u32(vendor_event,
752 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
753 stats->rxMcast ) ||
754 nla_put_u32(vendor_event,
755 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
756 stats->rxAmpdu ) ||
757 nla_put_u32(vendor_event,
758 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
759 stats->txAmpdu ) ||
760 nla_put_u32(vendor_event,
761 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
762 stats->mpduLost )||
763 nla_put_u32(vendor_event,
764 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
765 stats->retries ) ||
766 nla_put_u32(vendor_event,
767 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
768 stats->retriesShort ) ||
769 nla_put_u32(vendor_event,
770 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
771 stats->retriesLong ) ||
772 nla_put_u32(vendor_event,
773 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
774 stats->contentionTimeMin ) ||
775 nla_put_u32(vendor_event,
776 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
777 stats->contentionTimeMax ) ||
778 nla_put_u32(vendor_event,
779 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
780 stats->contentionTimeAvg ) ||
781 nla_put_u32(vendor_event,
782 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
783 stats->contentionNumSamples ))
784 {
785 hddLog(VOS_TRACE_LEVEL_ERROR,
786 FL("QCA_WLAN_VENDOR_ATTR put fail") );
787 return FALSE;
788 }
789 return TRUE;
790}
791
792static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
793 struct sk_buff *vendor_event)
794{
Dino Myclec8f3f332014-07-21 16:48:27 +0530795 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530796 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
797 nla_put(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
799 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
800 nla_put_u32(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
802 stats->state ) ||
803 nla_put_u32(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
805 stats->roaming ) ||
806 nla_put_u32(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
808 stats->capabilities ) ||
809 nla_put(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
811 strlen(stats->ssid), stats->ssid) ||
812 nla_put(vendor_event,
813 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
814 WNI_CFG_BSSID_LEN, stats->bssid) ||
815 nla_put(vendor_event,
816 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
817 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
818 nla_put(vendor_event,
819 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
820 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
821 )
822 {
823 hddLog(VOS_TRACE_LEVEL_ERROR,
824 FL("QCA_WLAN_VENDOR_ATTR put fail") );
825 return FALSE;
826 }
827 return TRUE;
828}
829
Dino Myclead7be522014-07-09 22:05:24 +0530830static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
831 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530832 struct sk_buff *vendor_event)
833{
834 int i = 0;
835 struct nlattr *wmmInfo;
Dino Myclead7be522014-07-09 22:05:24 +0530836 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
837 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasari1af54062014-11-15 16:13:37 +0530838 tSirWifiWmmAcStat accessclassStats;
Dino Myclead7be522014-07-09 22:05:24 +0530839
Sunil Duttc69bccb2014-05-26 21:30:20 +0530840 if (FALSE == put_wifi_interface_info(
841 &pWifiIfaceStat->info,
842 vendor_event))
843 {
844 hddLog(VOS_TRACE_LEVEL_ERROR,
845 FL("QCA_WLAN_VENDOR_ATTR put fail") );
846 return FALSE;
847
848 }
Dino Myclead7be522014-07-09 22:05:24 +0530849 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
850 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
851 if (NULL == pWifiIfaceStatTL)
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
854 return FALSE;
855 }
856
Srinivas Dasari1af54062014-11-15 16:13:37 +0530857 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
858 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
859 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
860 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
861
862 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Myclead7be522014-07-09 22:05:24 +0530866
867 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
868 {
869 if (VOS_STATUS_SUCCESS ==
870 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
871 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
872 {
873 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
874 * obtained from TL structure
875 */
876
877 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
878 pWifiIfaceStatTL->mgmtRx;
Dino Myclead7be522014-07-09 22:05:24 +0530879 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
880
Srinivas Dasarie004a892014-11-07 19:41:24 +0530881 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
882 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
883 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
884 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
885 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
886 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
887 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
888 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Myclead7be522014-07-09 22:05:24 +0530889
Srinivas Dasarie004a892014-11-07 19:41:24 +0530890 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
891 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
892 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
893 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
894 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
895 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
896 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
897 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Myclead7be522014-07-09 22:05:24 +0530898
Srinivas Dasarie004a892014-11-07 19:41:24 +0530899 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
900 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
902 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
903 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
904 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
905 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
906 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Myclead7be522014-07-09 22:05:24 +0530907 }
908 else
909 {
910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
911 }
912
Dino Myclead7be522014-07-09 22:05:24 +0530913 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
914 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
915 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
916 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
917 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
918 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
919 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
920 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
921 }
922 else
923 {
924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
925 }
926
927
Sunil Duttc69bccb2014-05-26 21:30:20 +0530928
929 if (nla_put_u32(vendor_event,
930 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
931 pWifiIfaceStat->beaconRx) ||
932 nla_put_u32(vendor_event,
933 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
934 pWifiIfaceStat->mgmtRx) ||
935 nla_put_u32(vendor_event,
936 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
937 pWifiIfaceStat->mgmtActionRx) ||
938 nla_put_u32(vendor_event,
939 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
940 pWifiIfaceStat->mgmtActionTx) ||
Dino Myclead7be522014-07-09 22:05:24 +0530941 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530942 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
943 pWifiIfaceStat->rssiMgmt) ||
Dino Myclead7be522014-07-09 22:05:24 +0530944 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
946 pWifiIfaceStat->rssiData) ||
Dino Myclead7be522014-07-09 22:05:24 +0530947 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
949 pWifiIfaceStat->rssiAck))
950 {
951 hddLog(VOS_TRACE_LEVEL_ERROR,
952 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Myclead7be522014-07-09 22:05:24 +0530953 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530954 return FALSE;
955 }
956
957 wmmInfo = nla_nest_start(vendor_event,
958 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
959 for (i = 0; i < WIFI_AC_MAX; i++)
960 {
961 struct nlattr *wmmStats;
962 wmmStats = nla_nest_start(vendor_event, i);
963 if (FALSE == put_wifi_wmm_ac_stat(
964 &pWifiIfaceStat->AccessclassStats[i],
965 vendor_event))
966 {
967 hddLog(VOS_TRACE_LEVEL_ERROR,
968 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Myclead7be522014-07-09 22:05:24 +0530969 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530970 return FALSE;
971 }
972
973 nla_nest_end(vendor_event, wmmStats);
974 }
975 nla_nest_end(vendor_event, wmmInfo);
Dino Myclead7be522014-07-09 22:05:24 +0530976 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530977 return TRUE;
978}
979
980static tSirWifiInterfaceMode
981 hdd_map_device_to_ll_iface_mode ( int deviceMode )
982{
983 switch (deviceMode)
984 {
985 case WLAN_HDD_INFRA_STATION:
986 return WIFI_INTERFACE_STA;
987 case WLAN_HDD_SOFTAP:
988 return WIFI_INTERFACE_SOFTAP;
989 case WLAN_HDD_P2P_CLIENT:
990 return WIFI_INTERFACE_P2P_CLIENT;
991 case WLAN_HDD_P2P_GO:
992 return WIFI_INTERFACE_P2P_GO;
993 case WLAN_HDD_IBSS:
994 return WIFI_INTERFACE_IBSS;
995 default:
Dino Myclec8f3f332014-07-21 16:48:27 +0530996 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530997 }
998}
999
1000static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1001 tpSirWifiInterfaceInfo pInfo)
1002{
1003 v_U8_t *staMac = NULL;
1004 hdd_station_ctx_t *pHddStaCtx;
1005 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1006 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1007
1008 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1009
1010 vos_mem_copy(pInfo->macAddr,
1011 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1012
1013 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1014 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1015 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1016 {
1017 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1018 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1019 {
1020 pInfo->state = WIFI_DISCONNECTED;
1021 }
1022 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1023 {
1024 hddLog(VOS_TRACE_LEVEL_ERROR,
1025 "%s: Session ID %d, Connection is in progress", __func__,
1026 pAdapter->sessionId);
1027 pInfo->state = WIFI_ASSOCIATING;
1028 }
1029 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1030 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1031 {
1032 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1033 hddLog(VOS_TRACE_LEVEL_ERROR,
1034 "%s: client " MAC_ADDRESS_STR
1035 " is in the middle of WPS/EAPOL exchange.", __func__,
1036 MAC_ADDR_ARRAY(staMac));
1037 pInfo->state = WIFI_AUTHENTICATING;
1038 }
1039 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1040 {
1041 pInfo->state = WIFI_ASSOCIATED;
1042 vos_mem_copy(pInfo->bssid,
1043 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1044 vos_mem_copy(pInfo->ssid,
1045 pHddStaCtx->conn_info.SSID.SSID.ssId,
1046 pHddStaCtx->conn_info.SSID.SSID.length);
1047 //NULL Terminate the string.
1048 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1049 }
1050 }
1051 vos_mem_copy(pInfo->countryStr,
1052 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1053
1054 vos_mem_copy(pInfo->apCountryStr,
1055 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1056
1057 return TRUE;
1058}
1059
1060/*
1061 * hdd_link_layer_process_peer_stats () - This function is called after
1062 * receiving Link Layer Peer statistics from FW.This function converts
1063 * the firmware data to the NL data and sends the same to the kernel/upper
1064 * layers.
1065 */
1066static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1067 v_VOID_t *pData)
1068{
1069 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1070 tpSirWifiRateStat pWifiRateStat;
1071 tpSirWifiPeerStat pWifiPeerStat;
1072 tpSirWifiPeerInfo pWifiPeerInfo;
1073 struct nlattr *peerInfo;
1074 struct sk_buff *vendor_event;
1075 int status, i;
1076
1077 status = wlan_hdd_validate_context(pHddCtx);
1078 if (0 != status)
1079 {
1080 hddLog(VOS_TRACE_LEVEL_ERROR,
1081 FL("HDD context is not valid") );
1082 return;
1083 }
1084
1085 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1086
1087 hddLog(VOS_TRACE_LEVEL_INFO,
1088 "LL_STATS_PEER_ALL : numPeers %u",
1089 pWifiPeerStat->numPeers);
1090 {
1091 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1092 {
1093 pWifiPeerInfo = (tpSirWifiPeerInfo)
1094 ((uint8 *)pWifiPeerStat->peerInfo +
1095 ( i * sizeof(tSirWifiPeerInfo)));
1096
Dasari Srinivas27748892014-10-19 13:03:41 +05301097 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1098 pWifiPeerInfo->type = WIFI_PEER_AP;
1099 }
1100 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1101 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1102 }
1103
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 hddLog(VOS_TRACE_LEVEL_INFO,
1105 " %d) LL_STATS Channel Stats "
1106 " Peer Type %u "
1107 " peerMacAddress %pM "
1108 " capabilities 0x%x "
1109 " numRate %u ",
1110 i,
1111 pWifiPeerInfo->type,
1112 pWifiPeerInfo->peerMacAddress,
1113 pWifiPeerInfo->capabilities,
1114 pWifiPeerInfo->numRate);
1115 {
1116 int j;
1117 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1118 {
1119 pWifiRateStat = (tpSirWifiRateStat)
1120 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1121 ( j * sizeof(tSirWifiRateStat)));
1122
1123 hddLog(VOS_TRACE_LEVEL_INFO,
1124 " peer Rate Stats "
1125 " preamble %u "
1126 " nss %u "
1127 " bw %u "
1128 " rateMcsIdx %u "
1129 " reserved %u "
1130 " bitrate %u "
1131 " txMpdu %u "
1132 " rxMpdu %u "
1133 " mpduLost %u "
1134 " retries %u "
1135 " retriesShort %u "
1136 " retriesLong %u",
1137 pWifiRateStat->rate.preamble,
1138 pWifiRateStat->rate.nss,
1139 pWifiRateStat->rate.bw,
1140 pWifiRateStat->rate.rateMcsIdx,
1141 pWifiRateStat->rate.reserved,
1142 pWifiRateStat->rate.bitrate,
1143 pWifiRateStat->txMpdu,
1144 pWifiRateStat->rxMpdu,
1145 pWifiRateStat->mpduLost,
1146 pWifiRateStat->retries,
1147 pWifiRateStat->retriesShort,
1148 pWifiRateStat->retriesLong);
1149 }
1150 }
1151 }
1152 }
1153
1154 /*
1155 * Allocate a size of 4096 for the peer stats comprising
1156 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1157 * sizeof (tSirWifiRateStat).Each field is put with an
1158 * NL attribute.The size of 4096 is considered assuming
1159 * that number of rates shall not exceed beyond 50 with
1160 * the sizeof (tSirWifiRateStat) being 32.
1161 */
1162 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1163 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1164 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1165 GFP_KERNEL);
1166 if (!vendor_event)
1167 {
1168 hddLog(VOS_TRACE_LEVEL_ERROR,
1169 "%s: cfg80211_vendor_event_alloc failed",
1170 __func__);
1171 return;
1172 }
1173 if (nla_put_u32(vendor_event,
1174 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1175 pWifiPeerStat->numPeers))
1176 {
1177 hddLog(VOS_TRACE_LEVEL_ERROR,
1178 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1179 kfree_skb(vendor_event);
1180 return;
1181 }
1182
1183 peerInfo = nla_nest_start(vendor_event,
1184 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1185
1186 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1187 pWifiPeerStat->peerInfo);
1188
1189 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1190 {
1191 struct nlattr *peers = nla_nest_start(vendor_event, i);
1192 int numRate = pWifiPeerInfo->numRate;
1193
1194 if (FALSE == put_wifi_peer_info(
1195 pWifiPeerInfo, vendor_event))
1196 {
1197 hddLog(VOS_TRACE_LEVEL_ERROR,
1198 "%s: put_wifi_peer_info put fail", __func__);
1199 kfree_skb(vendor_event);
1200 return;
1201 }
1202
1203 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1204 pWifiPeerStat->peerInfo +
1205 (i * sizeof(tSirWifiPeerInfo)) +
1206 (numRate * sizeof (tSirWifiRateStat)));
1207 nla_nest_end(vendor_event, peers);
1208 }
1209 nla_nest_end(vendor_event, peerInfo);
1210 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1211}
1212
1213/*
1214 * hdd_link_layer_process_iface_stats () - This function is called after
1215 * receiving Link Layer Interface statistics from FW.This function converts
1216 * the firmware data to the NL data and sends the same to the kernel/upper
1217 * layers.
1218 */
1219static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1220 v_VOID_t *pData)
1221{
1222 tpSirWifiIfaceStat pWifiIfaceStat;
1223 struct sk_buff *vendor_event;
1224 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1225 int status;
1226
1227 status = wlan_hdd_validate_context(pHddCtx);
1228 if (0 != status)
1229 {
1230 hddLog(VOS_TRACE_LEVEL_ERROR,
1231 FL("HDD context is not valid") );
1232 return;
1233 }
1234 /*
1235 * Allocate a size of 4096 for the interface stats comprising
1236 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1237 * assuming that all these fit with in the limit.Please take
1238 * a call on the limit based on the data requirements on
1239 * interface statistics.
1240 */
1241 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1242 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1243 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1244 GFP_KERNEL);
1245 if (!vendor_event)
1246 {
1247 hddLog(VOS_TRACE_LEVEL_ERROR,
1248 FL("cfg80211_vendor_event_alloc failed") );
1249 return;
1250 }
1251
1252 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1253
Dino Myclead7be522014-07-09 22:05:24 +05301254
1255 if (FALSE == hdd_get_interface_info( pAdapter,
1256 &pWifiIfaceStat->info))
1257 {
1258 hddLog(VOS_TRACE_LEVEL_ERROR,
1259 FL("hdd_get_interface_info get fail") );
1260 kfree_skb(vendor_event);
1261 return;
1262 }
1263
1264 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1265 vendor_event))
1266 {
1267 hddLog(VOS_TRACE_LEVEL_ERROR,
1268 FL("put_wifi_iface_stats fail") );
1269 kfree_skb(vendor_event);
1270 return;
1271 }
1272
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 hddLog(VOS_TRACE_LEVEL_INFO,
1274 "WMI_LINK_STATS_IFACE Data");
1275
1276 hddLog(VOS_TRACE_LEVEL_INFO,
1277 "LL_STATS_IFACE: "
1278 " Mode %u "
1279 " MAC %pM "
1280 " State %u "
1281 " Roaming %u "
1282 " capabilities 0x%x "
1283 " SSID %s "
1284 " BSSID %pM",
1285 pWifiIfaceStat->info.mode,
1286 pWifiIfaceStat->info.macAddr,
1287 pWifiIfaceStat->info.state,
1288 pWifiIfaceStat->info.roaming,
1289 pWifiIfaceStat->info.capabilities,
1290 pWifiIfaceStat->info.ssid,
1291 pWifiIfaceStat->info.bssid);
1292
1293 hddLog(VOS_TRACE_LEVEL_INFO,
1294 " AP country str: %c%c%c",
1295 pWifiIfaceStat->info.apCountryStr[0],
1296 pWifiIfaceStat->info.apCountryStr[1],
1297 pWifiIfaceStat->info.apCountryStr[2]);
1298
1299
1300 hddLog(VOS_TRACE_LEVEL_INFO,
1301 " Country Str Association: %c%c%c",
1302 pWifiIfaceStat->info.countryStr[0],
1303 pWifiIfaceStat->info.countryStr[1],
1304 pWifiIfaceStat->info.countryStr[2]);
1305
1306 hddLog(VOS_TRACE_LEVEL_INFO,
1307 " beaconRx %u "
1308 " mgmtRx %u "
1309 " mgmtActionRx %u "
1310 " mgmtActionTx %u "
Dino Myclead7be522014-07-09 22:05:24 +05301311 " rssiMgmt %d "
1312 " rssiData %d "
1313 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301314 pWifiIfaceStat->beaconRx,
1315 pWifiIfaceStat->mgmtRx,
1316 pWifiIfaceStat->mgmtActionRx,
1317 pWifiIfaceStat->mgmtActionTx,
1318 pWifiIfaceStat->rssiMgmt,
1319 pWifiIfaceStat->rssiData,
1320 pWifiIfaceStat->rssiAck );
1321
1322
1323 {
1324 int i;
1325 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1326 {
1327 hddLog(VOS_TRACE_LEVEL_INFO,
1328
1329 " %d) LL_STATS IFACE: "
1330 " ac: %u txMpdu: %u "
1331 " rxMpdu: %u txMcast: %u "
1332 " rxMcast: %u rxAmpdu: %u "
1333 " txAmpdu: %u mpduLost: %u "
1334 " retries: %u retriesShort: %u "
1335 " retriesLong: %u contentionTimeMin: %u "
1336 " contentionTimeMax: %u contentionTimeAvg: %u "
1337 " contentionNumSamples: %u",
1338 i,
1339 pWifiIfaceStat->AccessclassStats[i].ac,
1340 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1341 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1342 pWifiIfaceStat->AccessclassStats[i].txMcast,
1343 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1344 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1345 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1346 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1347 pWifiIfaceStat->AccessclassStats[i].retries,
1348 pWifiIfaceStat->
1349 AccessclassStats[i].retriesShort,
1350 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1351 pWifiIfaceStat->
1352 AccessclassStats[i].contentionTimeMin,
1353 pWifiIfaceStat->
1354 AccessclassStats[i].contentionTimeMax,
1355 pWifiIfaceStat->
1356 AccessclassStats[i].contentionTimeAvg,
1357 pWifiIfaceStat->
1358 AccessclassStats[i].contentionNumSamples);
1359
1360 }
1361 }
1362
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1364}
1365
1366/*
1367 * hdd_link_layer_process_radio_stats () - This function is called after
1368 * receiving Link Layer Radio statistics from FW.This function converts
1369 * the firmware data to the NL data and sends the same to the kernel/upper
1370 * layers.
1371 */
1372static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1373 v_VOID_t *pData)
1374{
1375 int status, i;
1376 tpSirWifiRadioStat pWifiRadioStat;
1377 tpSirWifiChannelStats pWifiChannelStats;
1378 struct sk_buff *vendor_event;
1379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1380 struct nlattr *chList;
1381
1382 status = wlan_hdd_validate_context(pHddCtx);
1383 if (0 != status)
1384 {
1385 hddLog(VOS_TRACE_LEVEL_ERROR,
1386 FL("HDD context is not valid") );
1387 return;
1388 }
1389 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1390
1391 hddLog(VOS_TRACE_LEVEL_INFO,
1392 "LL_STATS_RADIO"
1393 " radio is %d onTime is %u "
1394 " txTime is %u rxTime is %u "
1395 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301396 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301397 " onTimePnoScan is %u onTimeHs20 is %u "
1398 " numChannels is %u",
1399 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1400 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1401 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301402 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301403 pWifiRadioStat->onTimeRoamScan,
1404 pWifiRadioStat->onTimePnoScan,
1405 pWifiRadioStat->onTimeHs20,
1406 pWifiRadioStat->numChannels);
1407 /*
1408 * Allocate a size of 4096 for the Radio stats comprising
1409 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1410 * (tSirWifiChannelStats).Each channel data is put with an
1411 * NL attribute.The size of 4096 is considered assuming that
1412 * number of channels shall not exceed beyond 60 with the
1413 * sizeof (tSirWifiChannelStats) being 24 bytes.
1414 */
1415
1416 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1417 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1418 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1419 GFP_KERNEL);
1420
1421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
1424 FL("cfg80211_vendor_event_alloc failed") );
1425 return;
1426 }
1427
1428 if (nla_put_u32(vendor_event,
1429 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1430 pWifiRadioStat->radio) ||
1431 nla_put_u32(vendor_event,
1432 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1433 pWifiRadioStat->onTime) ||
1434 nla_put_u32(vendor_event,
1435 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1436 pWifiRadioStat->txTime) ||
1437 nla_put_u32(vendor_event,
1438 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1439 pWifiRadioStat->rxTime) ||
1440 nla_put_u32(vendor_event,
1441 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1442 pWifiRadioStat->onTimeScan) ||
1443 nla_put_u32(vendor_event,
1444 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1445 pWifiRadioStat->onTimeNbd) ||
1446 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301447 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1448 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 nla_put_u32(vendor_event,
1450 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1451 pWifiRadioStat->onTimeRoamScan) ||
1452 nla_put_u32(vendor_event,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1454 pWifiRadioStat->onTimePnoScan) ||
1455 nla_put_u32(vendor_event,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1457 pWifiRadioStat->onTimeHs20) ||
1458 nla_put_u32(vendor_event,
1459 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1460 pWifiRadioStat->numChannels))
1461 {
1462 hddLog(VOS_TRACE_LEVEL_ERROR,
1463 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1464 kfree_skb(vendor_event);
1465 return ;
1466 }
1467
1468 chList = nla_nest_start(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1470 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1471 {
1472 struct nlattr *chInfo;
1473
1474 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1475 pWifiRadioStat->channels +
1476 (i * sizeof(tSirWifiChannelStats)));
1477
1478 hddLog(VOS_TRACE_LEVEL_INFO,
1479 " %d) Channel Info"
1480 " width is %u "
1481 " CenterFreq %u "
1482 " CenterFreq0 %u "
1483 " CenterFreq1 %u "
1484 " onTime %u "
1485 " ccaBusyTime %u",
1486 i,
1487 pWifiChannelStats->channel.width,
1488 pWifiChannelStats->channel.centerFreq,
1489 pWifiChannelStats->channel.centerFreq0,
1490 pWifiChannelStats->channel.centerFreq1,
1491 pWifiChannelStats->onTime,
1492 pWifiChannelStats->ccaBusyTime);
1493
1494
1495 chInfo = nla_nest_start(vendor_event, i);
1496
1497 if (nla_put_u32(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1499 pWifiChannelStats->channel.width) ||
1500 nla_put_u32(vendor_event,
1501 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1502 pWifiChannelStats->channel.centerFreq) ||
1503 nla_put_u32(vendor_event,
1504 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1505 pWifiChannelStats->channel.centerFreq0) ||
1506 nla_put_u32(vendor_event,
1507 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1508 pWifiChannelStats->channel.centerFreq1) ||
1509 nla_put_u32(vendor_event,
1510 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1511 pWifiChannelStats->onTime) ||
1512 nla_put_u32(vendor_event,
1513 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1514 pWifiChannelStats->ccaBusyTime))
1515 {
1516 hddLog(VOS_TRACE_LEVEL_ERROR,
1517 FL("cfg80211_vendor_event_alloc failed") );
1518 kfree_skb(vendor_event);
1519 return ;
1520 }
1521 nla_nest_end(vendor_event, chInfo);
1522 }
1523 nla_nest_end(vendor_event, chList);
1524
1525 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1526 return;
1527}
1528
1529/*
1530 * hdd_link_layer_stats_ind_callback () - This function is called after
1531 * receiving Link Layer indications from FW.This callback converts the firmware
1532 * data to the NL data and send the same to the kernel/upper layers.
1533 */
1534static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1535 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301536 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301537{
Dino Mycled3d50022014-07-07 12:58:25 +05301538 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1539 hdd_adapter_t *pAdapter = NULL;
1540 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301541 int status;
1542
1543 status = wlan_hdd_validate_context(pHddCtx);
1544
1545 if (0 != status)
1546 {
1547 hddLog(VOS_TRACE_LEVEL_ERROR,
1548 FL("HDD context is not valid"));
1549 return;
1550 }
1551
Dino Mycled3d50022014-07-07 12:58:25 +05301552
1553
1554 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1555 if (NULL == pAdapter)
1556 {
1557 hddLog(VOS_TRACE_LEVEL_ERROR,
1558 FL(" MAC address %pM does not exist with host"),
1559 macAddr);
1560 return;
1561 }
1562
Sunil Duttc69bccb2014-05-26 21:30:20 +05301563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301564 "%s: Interface: %s LLStats indType: %d", __func__,
1565 pAdapter->dev->name, indType);
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 switch (indType)
1568 {
1569 case SIR_HAL_LL_STATS_RESULTS_RSP:
1570 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301571 hddLog(VOS_TRACE_LEVEL_INFO,
1572 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1573 hddLog(VOS_TRACE_LEVEL_INFO,
1574 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1575 linkLayerStatsResults->paramId);
1576 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301577 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1578 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 hddLog(VOS_TRACE_LEVEL_INFO,
1580 "LL_STATS RESULTS RESPONSE respId = %u",
1581 linkLayerStatsResults->respId);
1582 hddLog(VOS_TRACE_LEVEL_INFO,
1583 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1584 linkLayerStatsResults->moreResultToFollow);
1585 hddLog(VOS_TRACE_LEVEL_INFO,
1586 "LL_STATS RESULTS RESPONSE result = %p",
1587 linkLayerStatsResults->result);
1588 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1589 {
1590 hdd_link_layer_process_radio_stats(pAdapter,
1591 (v_VOID_t *)linkLayerStatsResults->result);
1592 }
1593 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1594 {
1595 hdd_link_layer_process_iface_stats(pAdapter,
1596 (v_VOID_t *)linkLayerStatsResults->result);
1597 }
1598 else if ( linkLayerStatsResults->paramId &
1599 WMI_LINK_STATS_ALL_PEER )
1600 {
1601 hdd_link_layer_process_peer_stats(pAdapter,
1602 (v_VOID_t *)linkLayerStatsResults->result);
1603 } /* WMI_LINK_STATS_ALL_PEER */
1604 else
1605 {
1606 hddLog(VOS_TRACE_LEVEL_ERROR,
1607 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1608 }
1609
1610 break;
1611 }
1612 default:
1613 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1614 break;
1615 }
1616 return;
1617}
1618
1619const struct
1620nla_policy
1621qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1622{
1623 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1624 { .type = NLA_U32 },
1625 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1626 { .type = NLA_U32 },
1627};
1628
1629static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1630 struct wireless_dev *wdev,
1631 void *data,
1632 int data_len)
1633{
1634 int status;
1635 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301636 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 struct net_device *dev = wdev->netdev;
1638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1639 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasarie004a892014-11-07 19:41:24 +05301640 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301641
1642 status = wlan_hdd_validate_context(pHddCtx);
1643 if (0 != status)
1644 {
1645 hddLog(VOS_TRACE_LEVEL_ERROR,
1646 FL("HDD context is not valid"));
1647 return -EINVAL;
1648 }
1649
1650 if (NULL == pAdapter)
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 FL("HDD adapter is Null"));
1654 return -ENODEV;
1655 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301656 /* check the LLStats Capability */
1657 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1658 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("Link Layer Statistics not supported by Firmware"));
1662 return -EINVAL;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664
1665 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1666 (struct nlattr *)data,
1667 data_len, qca_wlan_vendor_ll_set_policy))
1668 {
1669 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1670 return -EINVAL;
1671 }
1672 if (!tb_vendor
1673 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1674 {
1675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1676 return -EINVAL;
1677 }
1678 if (!tb_vendor[
1679 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1680 {
1681 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1682 return -EINVAL;
1683 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301685 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301686
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 nla_get_u32(
1689 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1690
Dino Mycledf0a5d92014-07-04 09:41:55 +05301691 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301692 nla_get_u32(
1693 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1694
Dino Mycled3d50022014-07-07 12:58:25 +05301695 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1696 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697
1698
1699 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301700 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301702 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 hddLog(VOS_TRACE_LEVEL_INFO,
1704 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301705 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706 hddLog(VOS_TRACE_LEVEL_INFO,
1707 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301708 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301709
1710 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1711 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301712 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301713 {
1714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1715 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301716 return -EINVAL;
1717
1718 }
Srinivas Dasarie004a892014-11-07 19:41:24 +05301719
1720 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1721 if (VOS_STATUS_SUCCESS !=
1722 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1723 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1726 "WLANTL_ClearInterfaceStats Failed", __func__);
1727 return -EINVAL;
1728 }
1729
1730 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1731 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1732 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1733 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1734
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301736 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301737 {
1738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1739 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301740 return -EINVAL;
1741 }
1742
1743 pAdapter->isLinkLayerStatsSet = 1;
1744
1745 return 0;
1746}
1747
1748const struct
1749nla_policy
1750qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1751{
1752 /* Unsigned 32bit value provided by the caller issuing the GET stats
1753 * command. When reporting
1754 * the stats results, the driver uses the same value to indicate
1755 * which GET request the results
1756 * correspond to.
1757 */
1758 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1759
1760 /* Unsigned 32bit value . bit mask to identify what statistics are
1761 requested for retrieval */
1762 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1763};
1764
1765static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1766 struct wireless_dev *wdev,
1767 void *data,
1768 int data_len)
1769{
1770 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1771 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301772 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 struct net_device *dev = wdev->netdev;
1774 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1775 int status;
1776
1777 status = wlan_hdd_validate_context(pHddCtx);
1778 if (0 != status)
1779 {
1780 hddLog(VOS_TRACE_LEVEL_ERROR,
1781 FL("HDD context is not valid"));
1782 return -EINVAL ;
1783 }
1784
1785 if (NULL == pAdapter)
1786 {
1787 hddLog(VOS_TRACE_LEVEL_FATAL,
1788 "%s: HDD adapter is Null", __func__);
1789 return -ENODEV;
1790 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301791 /* check the LLStats Capability */
1792 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1793 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1794 {
1795 hddLog(VOS_TRACE_LEVEL_ERROR,
1796 FL("Link Layer Statistics not supported by Firmware"));
1797 return -EINVAL;
1798 }
1799
Sunil Duttc69bccb2014-05-26 21:30:20 +05301800
1801 if (!pAdapter->isLinkLayerStatsSet)
1802 {
1803 hddLog(VOS_TRACE_LEVEL_FATAL,
1804 "%s: isLinkLayerStatsSet : %d",
1805 __func__, pAdapter->isLinkLayerStatsSet);
1806 return -EINVAL;
1807 }
1808
1809 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1810 (struct nlattr *)data,
1811 data_len, qca_wlan_vendor_ll_get_policy))
1812 {
1813 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1814 return -EINVAL;
1815 }
1816
1817 if (!tb_vendor
1818 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1819 {
1820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1821 return -EINVAL;
1822 }
1823
1824 if (!tb_vendor
1825 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1828 return -EINVAL;
1829 }
1830
Sunil Duttc69bccb2014-05-26 21:30:20 +05301831
Dino Mycledf0a5d92014-07-04 09:41:55 +05301832 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301833 nla_get_u32( tb_vendor[
1834 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301835 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836 nla_get_u32( tb_vendor[
1837 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1838
Dino Mycled3d50022014-07-07 12:58:25 +05301839 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1840 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301841
1842 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301843 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301845 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846 hddLog(VOS_TRACE_LEVEL_INFO,
1847 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301848 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301849
1850 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301851 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1854 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301855 return -EINVAL;
1856 }
1857 return 0;
1858}
1859
1860const struct
1861nla_policy
1862qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1863{
1864 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1865 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1866 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1867 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1868};
1869
1870static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1871 struct wireless_dev *wdev,
1872 void *data,
1873 int data_len)
1874{
1875 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1876 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301877 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301878 struct net_device *dev = wdev->netdev;
1879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1880 u32 statsClearReqMask;
1881 u8 stopReq;
1882 int status;
1883
1884 status = wlan_hdd_validate_context(pHddCtx);
1885 if (0 != status)
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR,
1888 FL("HDD context is not valid"));
1889 return -EINVAL;
1890 }
1891
1892 if (NULL == pAdapter)
1893 {
1894 hddLog(VOS_TRACE_LEVEL_FATAL,
1895 "%s: HDD adapter is Null", __func__);
1896 return -ENODEV;
1897 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 /* check the LLStats Capability */
1899 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1900 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR,
1903 FL("Enable LLStats Capability"));
1904 return -EINVAL;
1905 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906
1907 if (!pAdapter->isLinkLayerStatsSet)
1908 {
1909 hddLog(VOS_TRACE_LEVEL_FATAL,
1910 "%s: isLinkLayerStatsSet : %d",
1911 __func__, pAdapter->isLinkLayerStatsSet);
1912 return -EINVAL;
1913 }
1914
1915 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1916 (struct nlattr *)data,
1917 data_len, qca_wlan_vendor_ll_clr_policy))
1918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1920 return -EINVAL;
1921 }
1922
1923 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1924
1925 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1928 return -EINVAL;
1929
1930 }
1931
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932
Dino Mycledf0a5d92014-07-04 09:41:55 +05301933 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301934 nla_get_u32(
1935 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1936
Dino Mycledf0a5d92014-07-04 09:41:55 +05301937 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 nla_get_u8(
1939 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1940
1941 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301942 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301943
Dino Mycled3d50022014-07-07 12:58:25 +05301944 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1945 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946
1947 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301948 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301949 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301950 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 hddLog(VOS_TRACE_LEVEL_INFO,
1952 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301953 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301954 hddLog(VOS_TRACE_LEVEL_INFO,
1955 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301956 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957
1958 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301959 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301960 {
1961 struct sk_buff *temp_skbuff;
Srinivas Dasarie004a892014-11-07 19:41:24 +05301962 hdd_station_ctx_t *pHddStaCtx;
1963
1964 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1965 if (VOS_STATUS_SUCCESS !=
1966 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1967 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1970 "WLANTL_ClearInterfaceStats Failed", __func__);
1971 return -EINVAL;
1972 }
1973 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
1974 (statsClearReqMask & WIFI_STATS_IFACE)) {
1975 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1976 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1977 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1978 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1979 }
1980
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1982 2 * sizeof(u32) +
1983 NLMSG_HDRLEN);
1984
1985 if (temp_skbuff != NULL)
1986 {
1987
1988 if (nla_put_u32(temp_skbuff,
1989 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1990 statsClearReqMask) ||
1991 nla_put_u32(temp_skbuff,
1992 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1993 stopReq))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1996 kfree_skb(temp_skbuff);
1997 return -EINVAL;
1998 }
1999 /* If the ask is to stop the stats collection as part of clear
2000 * (stopReq = 1) , ensure that no further requests of get
2001 * go to the firmware by having isLinkLayerStatsSet set to 0.
2002 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302004 * case the firmware is just asked to clear the statistics.
2005 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302006 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 pAdapter->isLinkLayerStatsSet = 0;
2008 return cfg80211_vendor_cmd_reply(temp_skbuff);
2009 }
2010 return -ENOMEM;
2011 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012 return -EINVAL;
2013}
2014#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2015
Dino Mycle6fb96c12014-06-10 11:52:40 +05302016#ifdef WLAN_FEATURE_EXTSCAN
2017static const struct nla_policy
2018wlan_hdd_extscan_config_policy
2019 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2020{
2021 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2022 { .type = NLA_U32 },
2023 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2024 { .type = NLA_U32 },
2025 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2026 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2027 { .type = NLA_U32 },
2028 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2029 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2030
2031 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2032 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2033 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2034 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2035 { .type = NLA_U8 },
2036 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2037 { .type = NLA_U32 },
2038 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2039 { .type = NLA_U32 },
2040 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2041 { .type = NLA_U32 },
2042 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2043 { .type = NLA_U8 },
2044 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2045 { .type = NLA_U8 },
2046 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2047 { .type = NLA_U8 },
2048
2049 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2050 { .type = NLA_U32 },
2051 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2052 { .type = NLA_UNSPEC },
2053 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2054 { .type = NLA_S32 },
2055 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2056 { .type = NLA_S32 },
2057 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2058 { .type = NLA_U32 },
2059 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2060 { .type = NLA_U32 },
2061 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2062 { .type = NLA_U32 },
2063 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2064 = { .type = NLA_U32 },
2065 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2066 { .type = NLA_U32 },
2067 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2068 NLA_U32 },
2069};
2070
2071static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2072{
2073 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2074 struct sk_buff *skb = NULL;
2075 tpSirEXTScanCapabilitiesEvent pData =
2076 (tpSirEXTScanCapabilitiesEvent) pMsg;
2077
2078 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2080 "or pData(%p) is null"), pData);
2081 return;
2082 }
2083
2084 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2085 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2086 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2087 GFP_KERNEL);
2088
2089 if (!skb) {
2090 hddLog(VOS_TRACE_LEVEL_ERROR,
2091 FL("cfg80211_vendor_event_alloc failed"));
2092 return;
2093 }
2094
2095 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2096 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2097 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2098 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2099 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2100 pData->maxRssiSampleSize);
2101 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2102 pData->maxScanReportingThreshold);
2103 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2104 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2105 pData->maxSignificantWifiChangeAPs);
2106 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2107 pData->maxBsidHistoryEntries);
2108
2109 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2110 pData->requestId) ||
2111 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2112 nla_put_u32(skb,
2113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2114 pData->scanCacheSize) ||
2115 nla_put_u32(skb,
2116 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2117 pData->scanBuckets) ||
2118 nla_put_u32(skb,
2119 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2120 pData->maxApPerScan) ||
2121 nla_put_u32(skb,
2122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2123 pData->maxRssiSampleSize) ||
2124 nla_put_u32(skb,
2125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2126 pData->maxScanReportingThreshold) ||
2127 nla_put_u32(skb,
2128 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2129 pData->maxHotlistAPs) ||
2130 nla_put_u32(skb,
2131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2132 pData->maxSignificantWifiChangeAPs) ||
2133 nla_put_u32(skb,
2134 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2135 pData->maxBsidHistoryEntries)) {
2136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2137 goto nla_put_failure;
2138 }
2139
2140 cfg80211_vendor_event(skb, GFP_KERNEL);
2141 return;
2142
2143nla_put_failure:
2144 kfree_skb(skb);
2145 return;
2146}
2147
2148
2149static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2150{
2151 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2152 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2153 struct sk_buff *skb = NULL;
2154 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2155
2156
2157 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2159 "or pData(%p) is null"), pData);
2160 return;
2161 }
2162
2163 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2166 GFP_KERNEL);
2167
2168 if (!skb) {
2169 hddLog(VOS_TRACE_LEVEL_ERROR,
2170 FL("cfg80211_vendor_event_alloc failed"));
2171 return;
2172 }
2173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2174 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2175 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2176
2177 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2178 pData->requestId) ||
2179 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2181 goto nla_put_failure;
2182 }
2183
2184 /*
2185 * Store the Request ID for comparing with the requestID obtained
2186 * in other requests.HDD shall return a failure is the extscan_stop
2187 * request is issued with a different requestId as that of the
2188 * extscan_start request. Also, This requestId shall be used while
2189 * indicating the full scan results to the upper layers.
2190 * The requestId is stored with the assumption that the firmware
2191 * shall return the ext scan start request's requestId in ext scan
2192 * start response.
2193 */
2194 if (pData->status == 0)
2195 pMac->sme.extScanStartReqId = pData->requestId;
2196
2197
2198 cfg80211_vendor_event(skb, GFP_KERNEL);
2199 return;
2200
2201nla_put_failure:
2202 kfree_skb(skb);
2203 return;
2204}
2205
2206
2207static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2208{
2209 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2210 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2211 struct sk_buff *skb = NULL;
2212
2213 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2215 "or pData(%p) is null"), pData);
2216 return;
2217 }
2218
2219 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2220 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2221 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2222 GFP_KERNEL);
2223
2224 if (!skb) {
2225 hddLog(VOS_TRACE_LEVEL_ERROR,
2226 FL("cfg80211_vendor_event_alloc failed"));
2227 return;
2228 }
2229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2230 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2231
2232 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2233 pData->requestId) ||
2234 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2235 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2236 goto nla_put_failure;
2237 }
2238
2239 cfg80211_vendor_event(skb, GFP_KERNEL);
2240 return;
2241
2242nla_put_failure:
2243 kfree_skb(skb);
2244 return;
2245}
2246
2247
2248static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2249 void *pMsg)
2250{
2251 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2252 struct sk_buff *skb = NULL;
2253 tpSirEXTScanSetBssidHotListRspParams pData =
2254 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2255
2256 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2258 "or pData(%p) is null"), pData);
2259 return;
2260 }
2261 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2262 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2263 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2264 GFP_KERNEL);
2265
2266 if (!skb) {
2267 hddLog(VOS_TRACE_LEVEL_ERROR,
2268 FL("cfg80211_vendor_event_alloc failed"));
2269 return;
2270 }
2271 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2272 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2273 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2274
2275 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2276 pData->requestId) ||
2277 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2279 goto nla_put_failure;
2280 }
2281
2282 cfg80211_vendor_event(skb, GFP_KERNEL);
2283 return;
2284
2285nla_put_failure:
2286 kfree_skb(skb);
2287 return;
2288}
2289
2290static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2291 void *pMsg)
2292{
2293 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2294 struct sk_buff *skb = NULL;
2295 tpSirEXTScanResetBssidHotlistRspParams pData =
2296 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2297
2298 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2300 "or pData(%p) is null"), pData);
2301 return;
2302 }
2303
2304 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2305 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2306 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2307 GFP_KERNEL);
2308
2309 if (!skb) {
2310 hddLog(VOS_TRACE_LEVEL_ERROR,
2311 FL("cfg80211_vendor_event_alloc failed"));
2312 return;
2313 }
2314 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2315 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2316
2317 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2318 pData->requestId) ||
2319 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2321 goto nla_put_failure;
2322 }
2323
2324 cfg80211_vendor_event(skb, GFP_KERNEL);
2325 return;
2326
2327nla_put_failure:
2328 kfree_skb(skb);
2329 return;
2330}
2331
2332
2333static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2334 void *pMsg)
2335{
2336 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2337 struct sk_buff *skb = NULL;
2338 tpSirEXTScanSetSignificantChangeRspParams pData =
2339 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2340
2341 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2343 "or pData(%p) is null"), pData);
2344 return;
2345 }
2346
2347 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2348 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2349 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2350 GFP_KERNEL);
2351
2352 if (!skb) {
2353 hddLog(VOS_TRACE_LEVEL_ERROR,
2354 FL("cfg80211_vendor_event_alloc failed"));
2355 return;
2356 }
2357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2358 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2359 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2360
2361 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2362 pData->requestId) ||
2363 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2365 goto nla_put_failure;
2366 }
2367
2368 cfg80211_vendor_event(skb, GFP_KERNEL);
2369 return;
2370
2371nla_put_failure:
2372 kfree_skb(skb);
2373 return;
2374}
2375
2376
2377static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2378 void *pMsg)
2379{
2380 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2381 struct sk_buff *skb = NULL;
2382 tpSirEXTScanResetSignificantChangeRspParams pData =
2383 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2384
2385 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2387 "or pData(%p) is null"), pData);
2388 return;
2389 }
2390
2391 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2392 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2393 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2394 GFP_KERNEL);
2395
2396 if (!skb) {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 FL("cfg80211_vendor_event_alloc failed"));
2399 return;
2400 }
2401 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2402 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2403 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2404
2405 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2406 pData->requestId) ||
2407 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2408 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2409 goto nla_put_failure;
2410 }
2411
2412 cfg80211_vendor_event(skb, GFP_KERNEL);
2413 return;
2414
2415nla_put_failure:
2416 kfree_skb(skb);
2417 return;
2418}
2419
2420static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2421 void *pMsg)
2422{
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tANI_U32 i = 0, j, resultsPerEvent;
2426 tANI_S32 totalResults;
2427 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2428 tpSirWifiScanResult pSirWifiScanResult;
2429
2430 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2432 "or pData(%p) is null"), pData);
2433 return;
2434 }
2435 totalResults = pData->numOfAps;
2436 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2438 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2439
2440 do{
2441 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2442 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2443 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2444
2445 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2446 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2447 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2448 GFP_KERNEL);
2449
2450 if (!skb) {
2451 hddLog(VOS_TRACE_LEVEL_ERROR,
2452 FL("cfg80211_vendor_event_alloc failed"));
2453 return;
2454 }
2455
2456 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2457
2458 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2459 pData->requestId) ||
2460 nla_put_u32(skb,
2461 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2462 resultsPerEvent)) {
2463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2464 goto fail;
2465 }
2466 if (nla_put_u8(skb,
2467 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2468 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2469 {
2470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2471 goto fail;
2472 }
2473
2474 if (resultsPerEvent) {
2475 struct nlattr *aps;
2476
2477 aps = nla_nest_start(skb,
2478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2479 if (!aps)
2480 {
2481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2482 goto fail;
2483 }
2484
2485 for (j = 0; j < resultsPerEvent; j++, i++) {
2486 struct nlattr *ap;
2487 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2488 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2489
2490 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2491 "Ssid (%s)"
2492 "Bssid: %pM "
2493 "Channel (%u)"
2494 "Rssi (%d)"
2495 "RTT (%u)"
2496 "RTT_SD (%u)",
2497 i,
2498 pSirWifiScanResult->ts,
2499 pSirWifiScanResult->ssid,
2500 pSirWifiScanResult->bssid,
2501 pSirWifiScanResult->channel,
2502 pSirWifiScanResult->rssi,
2503 pSirWifiScanResult->rtt,
2504 pSirWifiScanResult->rtt_sd);
2505
2506 ap = nla_nest_start(skb, j + 1);
2507 if (!ap)
2508 {
2509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2510 goto fail;
2511 }
2512
2513 if (nla_put_u64(skb,
2514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2515 pSirWifiScanResult->ts) )
2516 {
2517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2518 goto fail;
2519 }
2520 if (nla_put(skb,
2521 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2522 sizeof(pSirWifiScanResult->ssid),
2523 pSirWifiScanResult->ssid) )
2524 {
2525 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2526 goto fail;
2527 }
2528 if (nla_put(skb,
2529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2530 sizeof(pSirWifiScanResult->bssid),
2531 pSirWifiScanResult->bssid) )
2532 {
2533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2534 goto fail;
2535 }
2536 if (nla_put_u32(skb,
2537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2538 pSirWifiScanResult->channel) )
2539 {
2540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2541 goto fail;
2542 }
Dasari Srinivas8aa7b262014-10-08 12:16:15 +05302543 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302544 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2545 pSirWifiScanResult->rssi) )
2546 {
2547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2548 goto fail;
2549 }
2550 if (nla_put_u32(skb,
2551 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2552 pSirWifiScanResult->rtt) )
2553 {
2554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2555 goto fail;
2556 }
2557 if (nla_put_u32(skb,
2558 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2559 pSirWifiScanResult->rtt_sd))
2560 {
2561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2562 goto fail;
2563 }
2564
2565 nla_nest_end(skb, ap);
2566 }
2567 nla_nest_end(skb, aps);
2568
2569 }
2570 cfg80211_vendor_event(skb, GFP_KERNEL);
2571 } while (totalResults > 0);
2572
2573 return;
2574fail:
2575 kfree_skb(skb);
2576 return;
2577}
2578
2579static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2580 void *pMsg)
2581{
2582 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2583 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2584 struct sk_buff *skb = NULL;
2585 tANI_U32 i;
2586
2587 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2589 "or pData(%p) is null"), pData);
2590 return;
2591 }
2592
2593 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2594 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2595 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2596 GFP_KERNEL);
2597
2598 if (!skb) {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 FL("cfg80211_vendor_event_alloc failed"));
2601 return;
2602 }
2603 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2604 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2606 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2607
2608 for (i = 0; i < pData->numOfAps; i++) {
2609 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2610 "Ssid (%s) "
2611 "Bssid (" MAC_ADDRESS_STR ") "
2612 "Channel (%u) "
2613 "Rssi (%d) "
2614 "RTT (%u) "
2615 "RTT_SD (%u) ",
2616 i,
2617 pData->ap[i].ts,
2618 pData->ap[i].ssid,
2619 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2620 pData->ap[i].channel,
2621 pData->ap[i].rssi,
2622 pData->ap[i].rtt,
2623 pData->ap[i].rtt_sd);
2624 }
2625
2626 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2627 pData->requestId) ||
2628 nla_put_u32(skb,
2629 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2630 pData->numOfAps)) {
2631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2632 goto fail;
2633 }
2634 if (pData->numOfAps) {
2635 struct nlattr *aps;
2636
2637 aps = nla_nest_start(skb,
2638 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2639 if (!aps)
2640 goto fail;
2641
2642 for (i = 0; i < pData->numOfAps; i++) {
2643 struct nlattr *ap;
2644
2645 ap = nla_nest_start(skb, i + 1);
2646 if (!ap)
2647 goto fail;
2648
2649 if (nla_put_u64(skb,
2650 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2651 pData->ap[i].ts) ||
2652 nla_put(skb,
2653 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2654 sizeof(pData->ap[i].ssid),
2655 pData->ap[i].ssid) ||
2656 nla_put(skb,
2657 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2658 sizeof(pData->ap[i].bssid),
2659 pData->ap[i].bssid) ||
2660 nla_put_u32(skb,
2661 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2662 pData->ap[i].channel) ||
2663 nla_put_s32(skb,
2664 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2665 pData->ap[i].rssi) ||
2666 nla_put_u32(skb,
2667 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2668 pData->ap[i].rtt) ||
2669 nla_put_u32(skb,
2670 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2671 pData->ap[i].rtt_sd))
2672 goto fail;
2673
2674 nla_nest_end(skb, ap);
2675 }
2676 nla_nest_end(skb, aps);
2677
2678 if (nla_put_u8(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2680 pData->moreData))
2681 goto fail;
2682 }
2683
2684 cfg80211_vendor_event(skb, GFP_KERNEL);
2685 return;
2686
2687fail:
2688 kfree_skb(skb);
2689 return;
2690
2691}
2692static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2693 void *pMsg)
2694{
2695 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2696 struct sk_buff *skb = NULL;
2697 tANI_U32 i, j;
2698 tpSirWifiSignificantChangeEvent pData =
2699 (tpSirWifiSignificantChangeEvent) pMsg;
2700
2701 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2703 "or pData(%p) is null"), pData);
2704 return;
2705 }
2706 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2707 EXTSCAN_EVENT_BUF_SIZE,
2708 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2709 GFP_KERNEL);
2710
2711 if (!skb) {
2712 hddLog(VOS_TRACE_LEVEL_ERROR,
2713 FL("cfg80211_vendor_event_alloc failed"));
2714 return;
2715 }
2716 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2717 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2718 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2719 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2720 pData->numSigRssiBss);
2721 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2722
2723 for (i = 0; i < pData->numSigRssiBss; i++) {
2724 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2725 " num RSSI %u ",
2726 i, pData->sigRssiResult[i].bssid,
2727 pData->sigRssiResult[i].channel,
2728 pData->sigRssiResult[i].numRssi);
2729
2730 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2731
2732 hddLog(VOS_TRACE_LEVEL_INFO,
2733 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302734 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302735
2736 }
2737 }
2738
2739
2740 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2741 pData->requestId) ||
2742 nla_put_u32(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2744 pData->numSigRssiBss)) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2746 goto fail;
2747 }
2748
2749 if (pData->numSigRssiBss) {
2750 struct nlattr *aps;
2751 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2752 if (!aps)
2753 goto fail;
2754 for (i = 0; i < pData->numSigRssiBss; i++) {
2755 struct nlattr *ap;
2756
2757 ap = nla_nest_start(skb, i);
2758 if (!ap)
2759 goto fail;
2760 if (nla_put(skb,
2761 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2762 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2763 nla_put_u32(skb,
2764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2765 pData->sigRssiResult[i].channel) ||
2766 nla_put_u32(skb,
2767 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2768 pData->sigRssiResult[i].numRssi) ||
2769 nla_put(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2771 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2772 pData->sigRssiResult[i].rssi))
2773 goto fail;
2774 nla_nest_end(skb, ap);
2775 }
2776 nla_nest_end(skb, aps);
2777 if (nla_put_u8(skb,
2778 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2779 pData->moreData))
2780 goto fail;
2781 }
2782 cfg80211_vendor_event(skb, GFP_KERNEL);
2783 return;
2784fail:
2785 kfree_skb(skb);
2786 return;
2787}
2788
2789static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2790 void *pMsg)
2791{
2792 struct sk_buff *skb;
2793 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2794 tpSirWifiFullScanResultEvent pData =
2795 (tpSirWifiFullScanResultEvent) (pMsg);
2796
2797 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2799 "or pData(%p) is null"), pData);
2800 return;
2801 }
2802
2803 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2804 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2805 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2806 GFP_KERNEL);
2807
2808 if (!skb) {
2809 hddLog(VOS_TRACE_LEVEL_ERROR,
2810 FL("cfg80211_vendor_event_alloc failed"));
2811 return;
2812 }
2813
2814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2816 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2817 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2818 "Ssid (%s)"
2819 "Bssid (" MAC_ADDRESS_STR ")"
2820 "Channel (%u)"
2821 "Rssi (%d)"
2822 "RTT (%u)"
2823 "RTT_SD (%u)"),
2824 pData->ap.ts,
2825 pData->ap.ssid,
2826 MAC_ADDR_ARRAY(pData->ap.bssid),
2827 pData->ap.channel,
2828 pData->ap.rssi,
2829 pData->ap.rtt,
2830 pData->ap.rtt_sd);
2831 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2832 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2833 pData->requestId) ||
2834 nla_put_u64(skb,
2835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2836 pData->ap.ts) ||
2837 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2838 sizeof(pData->ap.ssid),
2839 pData->ap.ssid) ||
2840 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2841 WNI_CFG_BSSID_LEN,
2842 pData->ap.bssid) ||
2843 nla_put_u32(skb,
2844 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2845 pData->ap.channel) ||
Dasari Srinivas8aa7b262014-10-08 12:16:15 +05302846 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302847 pData->ap.rssi) ||
2848 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2849 pData->ap.rtt) ||
2850 nla_put_u32(skb,
2851 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2852 pData->ap.rtt_sd) ||
2853 nla_put_u16(skb,
2854 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2855 pData->ap.beaconPeriod) ||
2856 nla_put_u16(skb,
2857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2858 pData->ap.capability) ||
2859 nla_put_u32(skb,
2860 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2861 pData->ieLength))
2862 {
2863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2864 goto nla_put_failure;
2865 }
2866 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2867 pData->ieLength,
2868 pData->ie))
2869 {
2870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2871 goto nla_put_failure;
2872 }
2873
2874 cfg80211_vendor_event(skb, GFP_KERNEL);
2875 return;
2876
2877nla_put_failure:
2878 kfree_skb(skb);
2879 return;
2880}
2881
2882static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2883 void *pMsg)
2884{
2885 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2886 struct sk_buff *skb = NULL;
2887 tpSirEXTScanResultsAvailableIndParams pData =
2888 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2889
2890 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2892 "or pData(%p) is null"), pData);
2893 return;
2894 }
2895
2896 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2897 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2898 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2899 GFP_KERNEL);
2900
2901 if (!skb) {
2902 hddLog(VOS_TRACE_LEVEL_ERROR,
2903 FL("cfg80211_vendor_event_alloc failed"));
2904 return;
2905 }
2906
2907 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2908 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2909 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2910 pData->numResultsAvailable);
2911 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2912 pData->requestId) ||
2913 nla_put_u32(skb,
2914 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2915 pData->numResultsAvailable)) {
2916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2917 goto nla_put_failure;
2918 }
2919
2920 cfg80211_vendor_event(skb, GFP_KERNEL);
2921 return;
2922
2923nla_put_failure:
2924 kfree_skb(skb);
2925 return;
2926}
2927
2928static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2929{
2930 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2931 struct sk_buff *skb = NULL;
2932 tpSirEXTScanProgressIndParams pData =
2933 (tpSirEXTScanProgressIndParams) pMsg;
2934
2935 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2937 "or pData(%p) is null"), pData);
2938 return;
2939 }
2940
2941 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2942 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2943 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2944 GFP_KERNEL);
2945
2946 if (!skb) {
2947 hddLog(VOS_TRACE_LEVEL_ERROR,
2948 FL("cfg80211_vendor_event_alloc failed"));
2949 return;
2950 }
2951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2952 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2953 pData->extScanEventType);
2954 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2955 pData->status);
2956
2957 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2958 pData->extScanEventType) ||
2959 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2961 pData->requestId) ||
2962 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2964 pData->status)) {
2965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2966 goto nla_put_failure;
2967 }
2968
2969 cfg80211_vendor_event(skb, GFP_KERNEL);
2970 return;
2971
2972nla_put_failure:
2973 kfree_skb(skb);
2974 return;
2975}
2976
2977void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2978 void *pMsg)
2979{
2980 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2981
2982 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivas43a90bb2014-10-08 13:03:08 +05302983 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302984 return;
2985 }
2986
2987 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2988
2989
2990 switch(evType) {
2991 case SIR_HAL_EXTSCAN_START_RSP:
2992 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2993 break;
2994
2995 case SIR_HAL_EXTSCAN_STOP_RSP:
2996 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2997 break;
2998 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2999 /* There is no need to send this response to upper layer
3000 Just log the message */
3001 hddLog(VOS_TRACE_LEVEL_INFO,
3002 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3003 break;
3004 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3005 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3006 break;
3007
3008 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3009 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3010 break;
3011
3012 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3013 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3014 break;
3015
3016 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3017 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3018 break;
3019 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3020 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3021 break;
3022 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3023 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3024 break;
3025 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3026 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3027 break;
3028 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3029 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3030 break;
3031 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3032 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3033 break;
3034 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3035 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3036 break;
3037 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3038 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3039 break;
3040 default:
3041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3042 break;
3043 }
3044}
3045
3046static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3047 struct wireless_dev *wdev,
3048 void *data, int dataLen)
3049{
Dino Myclee8843b32014-07-04 14:21:45 +05303050 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303051 struct net_device *dev = wdev->netdev;
3052 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3053 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3054 struct nlattr
3055 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3056 eHalStatus status;
3057
3058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3059 status = wlan_hdd_validate_context(pHddCtx);
3060 if (0 != status)
3061 {
3062 hddLog(VOS_TRACE_LEVEL_ERROR,
3063 FL("HDD context is not valid"));
3064 return -EINVAL;
3065 }
Dino Myclee8843b32014-07-04 14:21:45 +05303066 /* check the EXTScan Capability */
3067 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3068 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3069 {
3070 hddLog(VOS_TRACE_LEVEL_ERROR,
3071 FL("EXTScan not enabled/supported by Firmware"));
3072 return -EINVAL;
3073 }
3074
Dino Mycle6fb96c12014-06-10 11:52:40 +05303075 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3076 data, dataLen,
3077 wlan_hdd_extscan_config_policy)) {
3078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3079 return -EINVAL;
3080 }
3081
3082 /* Parse and fetch request Id */
3083 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3085 return -EINVAL;
3086 }
3087
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
Dino Myclee8843b32014-07-04 14:21:45 +05303089 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303090 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303091 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303092
Dino Myclee8843b32014-07-04 14:21:45 +05303093 reqMsg.sessionId = pAdapter->sessionId;
3094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303095
Dino Myclee8843b32014-07-04 14:21:45 +05303096 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303097 if (!HAL_STATUS_SUCCESS(status)) {
3098 hddLog(VOS_TRACE_LEVEL_ERROR,
3099 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303100 return -EINVAL;
3101 }
3102
3103 return 0;
3104}
3105
3106
3107static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3108 struct wireless_dev *wdev,
3109 void *data, int dataLen)
3110{
Dino Myclee8843b32014-07-04 14:21:45 +05303111 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303112 struct net_device *dev = wdev->netdev;
3113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3115 struct nlattr
3116 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3117 eHalStatus status;
3118
3119 status = wlan_hdd_validate_context(pHddCtx);
3120 if (0 != status)
3121 {
3122 hddLog(VOS_TRACE_LEVEL_ERROR,
3123 FL("HDD context is not valid"));
3124 return -EINVAL;
3125 }
Dino Myclee8843b32014-07-04 14:21:45 +05303126 /* check the EXTScan Capability */
3127 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3128 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR,
3131 FL("EXTScan not enabled/supported by Firmware"));
3132 return -EINVAL;
3133 }
3134
Dino Mycle6fb96c12014-06-10 11:52:40 +05303135 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3136 data, dataLen,
3137 wlan_hdd_extscan_config_policy)) {
3138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3139 return -EINVAL;
3140 }
3141 /* Parse and fetch request Id */
3142 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3143 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3144 return -EINVAL;
3145 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303146
Dino Myclee8843b32014-07-04 14:21:45 +05303147 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3149
Dino Myclee8843b32014-07-04 14:21:45 +05303150 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303151
Dino Myclee8843b32014-07-04 14:21:45 +05303152 reqMsg.sessionId = pAdapter->sessionId;
3153 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154
3155 /* Parse and fetch flush parameter */
3156 if (!tb
3157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3158 {
3159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3160 goto failed;
3161 }
Dino Myclee8843b32014-07-04 14:21:45 +05303162 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303163 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3164
Dino Myclee8843b32014-07-04 14:21:45 +05303165 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166
Dino Myclee8843b32014-07-04 14:21:45 +05303167 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303168 if (!HAL_STATUS_SUCCESS(status)) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 return -EINVAL;
3172 }
3173 return 0;
3174
3175failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303176 return -EINVAL;
3177}
3178
3179static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3180 struct wireless_dev *wdev,
3181 void *data, int dataLen)
3182{
3183 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3184 struct net_device *dev = wdev->netdev;
3185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3186 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3187 struct nlattr
3188 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3189 struct nlattr
3190 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3191 struct nlattr *apTh;
3192 eHalStatus status;
3193 tANI_U8 i = 0;
3194 int rem;
3195
3196 status = wlan_hdd_validate_context(pHddCtx);
3197 if (0 != status)
3198 {
3199 hddLog(VOS_TRACE_LEVEL_ERROR,
3200 FL("HDD context is not valid"));
3201 return -EINVAL;
3202 }
Dino Myclee8843b32014-07-04 14:21:45 +05303203 /* check the EXTScan Capability */
3204 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3205 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3206 {
3207 hddLog(VOS_TRACE_LEVEL_ERROR,
3208 FL("EXTScan not enabled/supported by Firmware"));
3209 return -EINVAL;
3210 }
3211
Dino Mycle6fb96c12014-06-10 11:52:40 +05303212 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3213 data, dataLen,
3214 wlan_hdd_extscan_config_policy)) {
3215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3216 return -EINVAL;
3217 }
3218
3219 /* Parse and fetch request Id */
3220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3221 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3222 return -EINVAL;
3223 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3225 vos_mem_malloc(sizeof(*pReqMsg));
3226 if (!pReqMsg) {
3227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3228 return -ENOMEM;
3229 }
3230
Dino Myclee8843b32014-07-04 14:21:45 +05303231
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 pReqMsg->requestId = nla_get_u32(
3233 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3235
3236 /* Parse and fetch number of APs */
3237 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3239 goto fail;
3240 }
3241
3242 pReqMsg->sessionId = pAdapter->sessionId;
3243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3244
3245 pReqMsg->numAp = nla_get_u32(
3246 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3248
3249 nla_for_each_nested(apTh,
3250 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3251 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3252 nla_data(apTh), nla_len(apTh),
3253 NULL)) {
3254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3255 goto fail;
3256 }
3257
3258 /* Parse and fetch MAC address */
3259 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3261 goto fail;
3262 }
3263 memcpy(pReqMsg->ap[i].bssid, nla_data(
3264 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3265 sizeof(tSirMacAddr));
3266 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3267
3268 /* Parse and fetch low RSSI */
3269 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3271 goto fail;
3272 }
3273 pReqMsg->ap[i].low = nla_get_s32(
3274 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3275 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3276
3277 /* Parse and fetch high RSSI */
3278 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3280 goto fail;
3281 }
3282 pReqMsg->ap[i].high = nla_get_s32(
3283 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3284 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3285 pReqMsg->ap[i].high);
3286
3287 /* Parse and fetch channel */
3288 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3290 goto fail;
3291 }
3292 pReqMsg->ap[i].channel = nla_get_u32(
3293 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3294 hddLog(VOS_TRACE_LEVEL_INFO,
3295 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3296 i++;
3297 }
3298 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3299 if (!HAL_STATUS_SUCCESS(status)) {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
3301 FL("sme_SetBssHotlist failed(err=%d)"), status);
3302 vos_mem_free(pReqMsg);
3303 return -EINVAL;
3304 }
3305
Dino Myclee8843b32014-07-04 14:21:45 +05303306 vos_mem_free(pReqMsg);
3307
Dino Mycle6fb96c12014-06-10 11:52:40 +05303308 return 0;
3309
3310fail:
3311 vos_mem_free(pReqMsg);
3312 return -EINVAL;
3313}
3314
3315static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3316 struct wireless_dev *wdev,
3317 void *data, int dataLen)
3318{
3319 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3320 struct net_device *dev = wdev->netdev;
3321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3323 struct nlattr
3324 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3325 struct nlattr
3326 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3327 struct nlattr *apTh;
3328 eHalStatus status;
3329 int i = 0;
3330 int rem;
3331
3332 status = wlan_hdd_validate_context(pHddCtx);
3333 if (0 != status)
3334 {
3335 hddLog(VOS_TRACE_LEVEL_ERROR,
3336 FL("HDD context is not valid"));
3337 return -EINVAL;
3338 }
Dino Myclee8843b32014-07-04 14:21:45 +05303339 /* check the EXTScan Capability */
3340 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3341 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3342 {
3343 hddLog(VOS_TRACE_LEVEL_ERROR,
3344 FL("EXTScan not enabled/supported by Firmware"));
3345 return -EINVAL;
3346 }
3347
Dino Mycle6fb96c12014-06-10 11:52:40 +05303348 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3349 data, dataLen,
3350 wlan_hdd_extscan_config_policy)) {
3351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3352 return -EINVAL;
3353 }
3354
3355 /* Parse and fetch request Id */
3356 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3358 return -EINVAL;
3359 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303361 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3364 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 }
3366
Dino Myclee8843b32014-07-04 14:21:45 +05303367
3368
Dino Mycle6fb96c12014-06-10 11:52:40 +05303369 pReqMsg->requestId = nla_get_u32(
3370 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3372
3373 /* Parse and fetch RSSI sample size */
3374 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3375 {
3376 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3377 goto fail;
3378 }
3379 pReqMsg->rssiSampleSize = nla_get_u32(
3380 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3381 hddLog(VOS_TRACE_LEVEL_INFO,
3382 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3383
3384 /* Parse and fetch lost AP sample size */
3385 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3386 {
3387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3388 goto fail;
3389 }
3390 pReqMsg->lostApSampleSize = nla_get_u32(
3391 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3392 hddLog(VOS_TRACE_LEVEL_INFO,
3393 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3394 /* Parse and fetch minimum Breaching */
3395 if (!tb
3396 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3398 goto fail;
3399 }
3400 pReqMsg->minBreaching = nla_get_u32(
3401 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3402 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3403
3404 /* Parse and fetch number of APs */
3405 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3407 goto fail;
3408 }
3409 pReqMsg->numAp = nla_get_u32(
3410 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3412
3413 pReqMsg->sessionId = pAdapter->sessionId;
3414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3415
3416 nla_for_each_nested(apTh,
3417 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3418 if(nla_parse(tb2,
3419 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3420 nla_data(apTh), nla_len(apTh),
3421 NULL)) {
3422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3423 goto fail;
3424 }
3425
3426 /* Parse and fetch MAC address */
3427 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3429 goto fail;
3430 }
3431 memcpy(pReqMsg->ap[i].bssid, nla_data(
3432 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3433 sizeof(tSirMacAddr));
3434
3435 /* Parse and fetch low RSSI */
3436 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3438 goto fail;
3439 }
3440 pReqMsg->ap[i].low = nla_get_s32(
3441 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3442 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3443
3444 /* Parse and fetch high RSSI */
3445 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3447 goto fail;
3448 }
3449 pReqMsg->ap[i].high = nla_get_s32(
3450 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3451 hddLog(VOS_TRACE_LEVEL_INFO,
3452 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3453
3454 /* Parse and fetch channel */
3455 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3457 goto fail;
3458 }
3459 pReqMsg->ap[i].channel = nla_get_u32(
3460 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3461 hddLog(VOS_TRACE_LEVEL_INFO,
3462 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3463 i++;
3464 }
3465
3466 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3467 if (!HAL_STATUS_SUCCESS(status)) {
3468 hddLog(VOS_TRACE_LEVEL_ERROR,
3469 FL("sme_SetSignificantChange failed(err=%d)"), status);
3470 vos_mem_free(pReqMsg);
3471 return -EINVAL;
3472 }
Dino Myclee8843b32014-07-04 14:21:45 +05303473 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3475 return 0;
3476
3477fail:
3478 vos_mem_free(pReqMsg);
3479 return -EINVAL;
3480}
3481
3482static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3483 struct wireless_dev *wdev,
3484 void *data, int dataLen)
3485{
3486 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3487 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3488 tANI_U8 numChannels = 0;
3489 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3490 tANI_U32 requestId;
3491 tWifiBand wifiBand;
3492 eHalStatus status;
3493 struct sk_buff *replySkb;
3494 tANI_U8 i;
3495
3496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3497 status = wlan_hdd_validate_context(pHddCtx);
3498 if (0 != status)
3499 {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("HDD context is not valid"));
3502 return -EINVAL;
3503 }
Dino Myclee8843b32014-07-04 14:21:45 +05303504 /* check the EXTScan Capability */
3505 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3506 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3507 {
3508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 FL("EXTScan not enabled/supported by Firmware"));
3510 return -EINVAL;
3511 }
3512
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3514 data, dataLen,
3515 wlan_hdd_extscan_config_policy)) {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3517 return -EINVAL;
3518 }
3519
3520 /* Parse and fetch request Id */
3521 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3523 return -EINVAL;
3524 }
3525 requestId = nla_get_u32(
3526 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3528
3529 /* Parse and fetch wifi band */
3530 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3531 {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3533 return -EINVAL;
3534 }
3535 wifiBand = nla_get_u32(
3536 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3537 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3538
3539 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3540 wifiBand, ChannelList,
3541 &numChannels);
3542 if (eHAL_STATUS_SUCCESS != status) {
3543 hddLog(VOS_TRACE_LEVEL_ERROR,
3544 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3545 return -EINVAL;
3546 }
3547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3548 for (i = 0; i < numChannels; i++)
3549 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3550
3551 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3552 sizeof(u32) * numChannels +
3553 NLMSG_HDRLEN);
3554
3555 if (!replySkb) {
3556 hddLog(VOS_TRACE_LEVEL_ERROR,
3557 FL("valid channels: buffer alloc fail"));
3558 return -EINVAL;
3559 }
3560 if (nla_put_u32(replySkb,
3561 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3562 numChannels) ||
3563 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3564 sizeof(u32) * numChannels, ChannelList)) {
3565
3566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3567 kfree_skb(replySkb);
3568 return -EINVAL;
3569 }
3570
3571 return cfg80211_vendor_cmd_reply(replySkb);
3572}
3573
3574static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3575 struct wireless_dev *wdev,
3576 void *data, int dataLen)
3577{
Dino Myclee8843b32014-07-04 14:21:45 +05303578 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579 struct net_device *dev = wdev->netdev;
3580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3581 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3582 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3583 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3584 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3585 struct nlattr *buckets;
3586 struct nlattr *channels;
3587 int rem1;
3588 int rem2;
3589 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303590 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591
3592 status = wlan_hdd_validate_context(pHddCtx);
3593 if (0 != status)
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR,
3596 FL("HDD context is not valid"));
3597 return -EINVAL;
3598 }
Dino Myclee8843b32014-07-04 14:21:45 +05303599 /* check the EXTScan Capability */
3600 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3601 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3602 {
3603 hddLog(VOS_TRACE_LEVEL_ERROR,
3604 FL("EXTScan not enabled/supported by Firmware"));
3605 return -EINVAL;
3606 }
3607
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3609 data, dataLen,
3610 wlan_hdd_extscan_config_policy)) {
3611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3612 return -EINVAL;
3613 }
3614
3615 /* Parse and fetch request Id */
3616 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3618 return -EINVAL;
3619 }
3620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 pReqMsg = (tpSirEXTScanStartReqParams)
3622 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3625 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626 }
3627
3628 pReqMsg->requestId = nla_get_u32(
3629 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3630 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3631
3632 pReqMsg->sessionId = pAdapter->sessionId;
3633 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3634
3635 /* Parse and fetch base period */
3636 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3638 goto fail;
3639 }
3640 pReqMsg->basePeriod = nla_get_u32(
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3642 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3643 pReqMsg->basePeriod);
3644
3645 /* Parse and fetch max AP per scan */
3646 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3648 goto fail;
3649 }
3650 pReqMsg->maxAPperScan = nla_get_u32(
3651 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3653 pReqMsg->maxAPperScan);
3654
3655 /* Parse and fetch report threshold */
3656 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3658 goto fail;
3659 }
3660 pReqMsg->reportThreshold = nla_get_u8(
3661 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3663 pReqMsg->reportThreshold);
3664
3665 /* Parse and fetch number of buckets */
3666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3668 goto fail;
3669 }
3670 pReqMsg->numBuckets = nla_get_u8(
3671 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3672 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3673 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3674 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3675 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3676 }
3677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3678 pReqMsg->numBuckets);
3679 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3681 goto fail;
3682 }
3683
3684 nla_for_each_nested(buckets,
3685 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3686 if(nla_parse(bucket,
3687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3688 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3690 goto fail;
3691 }
3692
3693 /* Parse and fetch bucket spec */
3694 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3696 goto fail;
3697 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303698
3699 pReqMsg->buckets[index].bucket = nla_get_u8(
3700 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3701
3702 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3703 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704
3705 /* Parse and fetch wifi band */
3706 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3708 goto fail;
3709 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303710 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3712 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303713 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303714
3715 /* Parse and fetch period */
3716 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3718 goto fail;
3719 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303720 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3722 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303723 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724
3725 /* Parse and fetch report events */
3726 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3728 goto fail;
3729 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303730 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303731 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3732 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303733 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303734
3735 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303736 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3737 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3739 goto fail;
3740 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303741 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3743 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303744 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303745
3746 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3748 goto fail;
3749 }
3750
3751 j = 0;
3752 nla_for_each_nested(channels,
3753 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3754 if(nla_parse(channel,
3755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3756 nla_data(channels), nla_len(channels),
3757 NULL)) { //wlan_hdd_extscan_config_policy here
3758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3759 goto fail;
3760 }
3761
3762 /* Parse and fetch channel */
3763 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3765 goto fail;
3766 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303767 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3769 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303770 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 /* Parse and fetch dwell time */
3773 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3775 goto fail;
3776 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303777 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303780 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781
3782 /* Parse and fetch channel spec passive */
3783 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("attr channel spec passive failed"));
3786 goto fail;
3787 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303788 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303791 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792 j++;
3793 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303794 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303795 }
3796 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3797 if (!HAL_STATUS_SUCCESS(status)) {
3798 hddLog(VOS_TRACE_LEVEL_ERROR,
3799 FL("sme_EXTScanStart failed(err=%d)"), status);
3800 vos_mem_free(pReqMsg);
3801 return -EINVAL;
3802 }
3803
Dino Myclee8843b32014-07-04 14:21:45 +05303804 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303805 return 0;
3806
3807fail:
3808 vos_mem_free(pReqMsg);
3809 return -EINVAL;
3810}
3811
3812static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3813 struct wireless_dev *wdev,
3814 void *data, int dataLen)
3815{
Dino Myclee8843b32014-07-04 14:21:45 +05303816 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303817 struct net_device *dev = wdev->netdev;
3818 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3819 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3820 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3821 eHalStatus status;
3822
3823 status = wlan_hdd_validate_context(pHddCtx);
3824 if (0 != status)
3825 {
3826 hddLog(VOS_TRACE_LEVEL_ERROR,
3827 FL("HDD context is not valid"));
3828 return -EINVAL;
3829 }
Dino Myclee8843b32014-07-04 14:21:45 +05303830 /* check the EXTScan Capability */
3831 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3832 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR,
3835 FL("EXTScan not enabled/supported by Firmware"));
3836 return -EINVAL;
3837 }
3838
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3840 data, dataLen,
3841 wlan_hdd_extscan_config_policy)) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3843 return -EINVAL;
3844 }
3845
3846 /* Parse and fetch request Id */
3847 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3849 return -EINVAL;
3850 }
3851
Dino Myclee8843b32014-07-04 14:21:45 +05303852 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303853 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303854 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303855
Dino Myclee8843b32014-07-04 14:21:45 +05303856 reqMsg.sessionId = pAdapter->sessionId;
3857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303858
Dino Myclee8843b32014-07-04 14:21:45 +05303859 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303860 if (!HAL_STATUS_SUCCESS(status)) {
3861 hddLog(VOS_TRACE_LEVEL_ERROR,
3862 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863 return -EINVAL;
3864 }
3865
3866 return 0;
3867}
3868
3869static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3870 struct wireless_dev *wdev,
3871 void *data, int dataLen)
3872{
Dino Myclee8843b32014-07-04 14:21:45 +05303873 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 struct net_device *dev = wdev->netdev;
3875 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3876 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3877 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3878 eHalStatus status;
3879
3880 status = wlan_hdd_validate_context(pHddCtx);
3881 if (0 != status)
3882 {
3883 hddLog(VOS_TRACE_LEVEL_ERROR,
3884 FL("HDD context is not valid"));
3885 return -EINVAL;
3886 }
Dino Myclee8843b32014-07-04 14:21:45 +05303887 /* check the EXTScan Capability */
3888 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3889 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3890 {
3891 hddLog(VOS_TRACE_LEVEL_ERROR,
3892 FL("EXTScan not enabled/supported by Firmware"));
3893 return -EINVAL;
3894 }
3895
Dino Mycle6fb96c12014-06-10 11:52:40 +05303896 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3897 data, dataLen,
3898 wlan_hdd_extscan_config_policy)) {
3899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3900 return -EINVAL;
3901 }
3902
3903 /* Parse and fetch request Id */
3904 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3906 return -EINVAL;
3907 }
3908
Dino Myclee8843b32014-07-04 14:21:45 +05303909 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303911 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912
Dino Myclee8843b32014-07-04 14:21:45 +05303913 reqMsg.sessionId = pAdapter->sessionId;
3914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Dino Myclee8843b32014-07-04 14:21:45 +05303916 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 if (!HAL_STATUS_SUCCESS(status)) {
3918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920 return -EINVAL;
3921 }
3922
3923 return 0;
3924}
3925
3926static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3927 struct wiphy *wiphy,
3928 struct wireless_dev *wdev,
3929 void *data, int dataLen)
3930{
Dino Myclee8843b32014-07-04 14:21:45 +05303931 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303932 struct net_device *dev = wdev->netdev;
3933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3934 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3935 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3936 eHalStatus status;
3937
3938 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3939 status = wlan_hdd_validate_context(pHddCtx);
3940 if (0 != status)
3941 {
3942 hddLog(VOS_TRACE_LEVEL_ERROR,
3943 FL("HDD context is not valid"));
3944 return -EINVAL;
3945 }
Dino Myclee8843b32014-07-04 14:21:45 +05303946 /* check the EXTScan Capability */
3947 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3948 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 FL("EXTScan not enabled/supported by Firmware"));
3952 return -EINVAL;
3953 }
3954
Dino Mycle6fb96c12014-06-10 11:52:40 +05303955 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3956 data, dataLen,
3957 wlan_hdd_extscan_config_policy)) {
3958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3959 return -EINVAL;
3960 }
3961
3962 /* Parse and fetch request Id */
3963 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3965 return -EINVAL;
3966 }
3967
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968
Dino Myclee8843b32014-07-04 14:21:45 +05303969 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303971 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972
Dino Myclee8843b32014-07-04 14:21:45 +05303973 reqMsg.sessionId = pAdapter->sessionId;
3974 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975
Dino Myclee8843b32014-07-04 14:21:45 +05303976 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977 if (!HAL_STATUS_SUCCESS(status)) {
3978 hddLog(VOS_TRACE_LEVEL_ERROR,
3979 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980 return -EINVAL;
3981 }
3982
3983 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3984 return 0;
3985}
3986
3987#endif /* WLAN_FEATURE_EXTSCAN */
3988
Atul Mittal115287b2014-07-08 13:26:33 +05303989/*EXT TDLS*/
3990static const struct nla_policy
3991wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
3992{
3993 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
3994 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
3995 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
3996 {.type = NLA_S32 },
3997 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
3998 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
3999
4000};
4001
4002static const struct nla_policy
4003wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4004{
4005 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4006
4007};
4008
4009static const struct nla_policy
4010wlan_hdd_tdls_config_state_change_policy[
4011 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4012{
4013 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4014 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4015 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304016 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4017 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4018 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304019
4020};
4021
4022static const struct nla_policy
4023wlan_hdd_tdls_config_get_status_policy[
4024 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4025{
4026 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4027 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4028 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304029 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4030 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4031 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304032
4033};
Siddharth Bhal2a73cfd2014-09-29 21:13:13 +05304034
4035static const struct nla_policy
4036wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4037{
4038 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4039};
4040
4041static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4042 struct wireless_dev *wdev,
4043 void *data,
4044 int data_len)
4045{
4046
4047 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4048 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4049
4050 if (0 != wlan_hdd_validate_context(pHddCtx)){
4051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4052 return -EINVAL;
4053 }
4054 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4056 return -ENOTSUPP;
4057 }
4058 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4060 return -ENOTSUPP;
4061 }
4062
4063 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4064 data, data_len, wlan_hdd_mac_config)) {
4065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4066 return -EINVAL;
4067 }
4068
4069 /* Parse and fetch mac address */
4070 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4072 return -EINVAL;
4073 }
4074
4075 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4076 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4077 VOS_MAC_ADDR_LAST_3_BYTES);
4078
4079 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,nla_data(
4080 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4081 VOS_MAC_ADDR_FIRST_3_BYTES);
4082
4083 if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes(
4084 (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]),
4085 VOS_MAC_ADDR_LAST_3_BYTES)) {
4086 hddLog(LOGE, FL("Failed to generate random Mac Addr"));
4087 }
4088 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4089 pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4090 VOS_MAC_ADDR_SIZE);
4091
4092 if (eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal,
4093 &pHddCtx->spoofMacAddr.randomMacAddr)) {
4094 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4095 }
4096
4097 return 0;
4098}
4099
Atul Mittal115287b2014-07-08 13:26:33 +05304100static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 void *data,
4103 int data_len)
4104{
4105 u8 peer[6] = {0};
4106 struct net_device *dev = wdev->netdev;
4107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4108 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4109 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4110 eHalStatus ret;
4111 tANI_S32 state;
4112 tANI_S32 reason;
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304113 tANI_S32 global_operating_class = 0;
4114 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304115 struct sk_buff *skb = NULL;
4116
4117 ret = wlan_hdd_validate_context(pHddCtx);
4118 if (0 != ret) {
4119
4120 return -EINVAL;
4121 }
4122 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4123
4124 return -ENOTSUPP;
4125 }
4126 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4127 data, data_len,
4128 wlan_hdd_tdls_config_get_status_policy)) {
4129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4130 return -EINVAL;
4131 }
4132
4133 /* Parse and fetch mac address */
4134 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4136 return -EINVAL;
4137 }
4138
4139 memcpy(peer, nla_data(
4140 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4141 sizeof(peer));
4142 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4143
4144 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4145
4146 if (0 != ret) {
4147 hddLog(VOS_TRACE_LEVEL_ERROR,
4148 FL("get status Failed"));
4149 return -EINVAL;
4150 }
4151 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304152 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304153 NLMSG_HDRLEN);
4154
4155 if (!skb) {
4156 hddLog(VOS_TRACE_LEVEL_ERROR,
4157 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4158 return -EINVAL;
4159 }
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304161 reason,
4162 state,
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304163 global_operating_class,
4164 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304165 MAC_ADDR_ARRAY(peer));
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304166 if (nla_put_s32(skb,
4167 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4168 state) ||
4169 nla_put_s32(skb,
4170 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4171 reason) ||
4172 nla_put_s32(skb,
4173 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4174 global_operating_class) ||
4175 nla_put_s32(skb,
4176 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4177 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304178
4179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4180 goto nla_put_failure;
4181 }
4182
4183 return cfg80211_vendor_cmd_reply(skb);
4184
4185nla_put_failure:
4186 kfree_skb(skb);
4187 return -EINVAL;
4188}
4189
4190static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4191 tANI_S32 state,
4192 tANI_S32 reason,
4193 void *ctx)
4194{
4195 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4196 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4197 struct sk_buff *skb = NULL;
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304198 tANI_S32 global_operating_class = 0;
4199 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304200
4201 if (wlan_hdd_validate_context(pHddCtx)) {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4203 return -EINVAL;
4204 }
4205
4206 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4207
4208 return -ENOTSUPP;
4209 }
4210 skb = cfg80211_vendor_event_alloc(
4211 pHddCtx->wiphy,
4212 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4213 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4214 GFP_KERNEL);
4215
4216 if (!skb) {
4217 hddLog(VOS_TRACE_LEVEL_ERROR,
4218 FL("cfg80211_vendor_event_alloc failed"));
4219 return -EINVAL;
4220 }
4221 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304222 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4223 reason,
4224 state,
4225 global_operating_class,
4226 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304227 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4228 MAC_ADDR_ARRAY(mac));
4229
Atul Mittal2acd2fe2014-10-16 15:26:38 +05304230 if (nla_put(skb,
4231 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4232 VOS_MAC_ADDR_SIZE, mac) ||
4233 nla_put_s32(skb,
4234 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4235 state) ||
4236 nla_put_s32(skb,
4237 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4238 reason) ||
4239 nla_put_s32(skb,
4240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4241 channel) ||
4242 nla_put_s32(skb,
4243 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4244 global_operating_class)
4245 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4247 goto nla_put_failure;
4248 }
4249
4250 cfg80211_vendor_event(skb, GFP_KERNEL);
4251 return (0);
4252
4253nla_put_failure:
4254 kfree_skb(skb);
4255 return -EINVAL;
4256}
4257
4258static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4259 struct wireless_dev *wdev,
4260 void *data,
4261 int data_len)
4262{
4263 u8 peer[6] = {0};
4264 struct net_device *dev = wdev->netdev;
4265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4266 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4267 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4268 eHalStatus status;
4269 tdls_req_params_t pReqMsg = {0};
4270
4271 status = wlan_hdd_validate_context(pHddCtx);
4272 if (0 != status) {
4273 hddLog(VOS_TRACE_LEVEL_ERROR,
4274 FL("HDD context is not valid"));
4275 return -EINVAL;
4276 }
4277 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4278
4279 return -ENOTSUPP;
4280 }
4281 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4282 data, data_len,
4283 wlan_hdd_tdls_config_enable_policy)) {
4284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4285 return -EINVAL;
4286 }
4287
4288 /* Parse and fetch mac address */
4289 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4291 return -EINVAL;
4292 }
4293
4294 memcpy(peer, nla_data(
4295 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4296 sizeof(peer));
4297 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4298
4299 /* Parse and fetch channel */
4300 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4302 return -EINVAL;
4303 }
4304 pReqMsg.channel = nla_get_s32(
4305 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4306 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4307
4308 /* Parse and fetch global operating class */
4309 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4311 return -EINVAL;
4312 }
4313 pReqMsg.global_operating_class = nla_get_s32(
4314 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4316 pReqMsg.global_operating_class);
4317
4318 /* Parse and fetch latency ms */
4319 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4320 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4321 return -EINVAL;
4322 }
4323 pReqMsg.max_latency_ms = nla_get_s32(
4324 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4326 pReqMsg.max_latency_ms);
4327
4328 /* Parse and fetch required bandwidth kbps */
4329 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4331 return -EINVAL;
4332 }
4333
4334 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4335 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4336 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4337 pReqMsg.min_bandwidth_kbps);
4338
4339 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4340 peer,
4341 wlan_hdd_cfg80211_exttdls_callback));
4342}
4343
4344static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4345 struct wireless_dev *wdev,
4346 void *data,
4347 int data_len)
4348{
4349 u8 peer[6] = {0};
4350 struct net_device *dev = wdev->netdev;
4351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4352 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4353 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4354 eHalStatus status;
4355
4356 status = wlan_hdd_validate_context(pHddCtx);
4357 if (0 != status) {
4358 hddLog(VOS_TRACE_LEVEL_ERROR,
4359 FL("HDD context is not valid"));
4360 return -EINVAL;
4361 }
4362 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4363
4364 return -ENOTSUPP;
4365 }
4366 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4367 data, data_len,
4368 wlan_hdd_tdls_config_disable_policy)) {
4369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4370 return -EINVAL;
4371 }
4372 /* Parse and fetch mac address */
4373 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4375 return -EINVAL;
4376 }
4377
4378 memcpy(peer, nla_data(
4379 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4380 sizeof(peer));
4381 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4382
4383 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4384}
4385
Dasari Srinivasf70e8fc2014-09-26 17:50:57 +05304386static int
4387wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4388 struct wireless_dev *wdev,
4389 void *data, int data_len)
4390{
4391 struct net_device *dev = wdev->netdev;
4392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4393 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4394 struct sk_buff *skb = NULL;
4395 tANI_U32 fset = 0;
4396
4397 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4398 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4399 fset |= WIFI_FEATURE_INFRA;
4400 }
4401
4402 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4403 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4404 fset |= WIFI_FEATURE_INFRA_5G;
4405 }
4406
4407#ifdef WLAN_FEATURE_P2P
4408 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4409 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4410 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4411 fset |= WIFI_FEATURE_P2P;
4412 }
4413#endif
4414
4415 /* Soft-AP is supported currently by default */
4416 fset |= WIFI_FEATURE_SOFT_AP;
4417
Kanchanapally, Vidyullathadc7d2152015-03-24 16:58:38 +05304418 /* HOTSPOT is a supplicant feature, enable it by default */
4419 fset |= WIFI_FEATURE_HOTSPOT;
4420
Dasari Srinivasf70e8fc2014-09-26 17:50:57 +05304421#ifdef WLAN_FEATURE_EXTSCAN
4422 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4423 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4424 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4425 fset |= WIFI_FEATURE_EXTSCAN;
4426 }
4427#endif
4428
4429#ifdef WLAN_FEATURE_NAN
4430 if (sme_IsFeatureSupportedByFW(NAN)) {
4431 hddLog(LOG1, FL("NAN is supported by firmware"));
4432 fset |= WIFI_FEATURE_NAN;
4433 }
4434#endif
4435
4436 /* D2D RTT is not supported currently by default */
4437 if (sme_IsFeatureSupportedByFW(RTT)) {
4438 hddLog(LOG1, FL("RTT is supported by firmware"));
4439 fset |= WIFI_FEATURE_D2AP_RTT;
4440 }
4441
4442#ifdef FEATURE_WLAN_BATCH_SCAN
4443 if (fset & WIFI_FEATURE_EXTSCAN) {
4444 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4445 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4446 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4447 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4448 fset |= WIFI_FEATURE_BATCH_SCAN;
4449 }
4450#endif
4451
4452#ifdef FEATURE_WLAN_SCAN_PNO
4453 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4454 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4455 hddLog(LOG1, FL("PNO is supported by firmware"));
4456 fset |= WIFI_FEATURE_PNO;
4457 }
4458#endif
4459
4460 /* STA+STA is supported currently by default */
4461 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4462
4463#ifdef FEATURE_WLAN_TDLS
4464 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4465 sme_IsFeatureSupportedByFW(TDLS)) {
4466 hddLog(LOG1, FL("TDLS is supported by firmware"));
4467 fset |= WIFI_FEATURE_TDLS;
4468 }
4469
4470 /* TDLS_OFFCHANNEL is not supported currently by default */
4471#endif
4472
4473#ifdef WLAN_AP_STA_CONCURRENCY
4474 /* AP+STA concurrency is supported currently by default */
4475 fset |= WIFI_FEATURE_AP_STA;
4476#endif
4477
4478 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4479 NLMSG_HDRLEN);
4480
4481 if (!skb) {
4482 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4483 return -EINVAL;
4484 }
4485 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4486
4487 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4488 hddLog(LOGE, FL("nla put fail"));
4489 goto nla_put_failure;
4490 }
4491
4492 return cfg80211_vendor_cmd_reply(skb);
4493
4494nla_put_failure:
4495 kfree_skb(skb);
4496 return -EINVAL;
4497}
4498
Dasari Srinivasbee4dce2014-10-28 17:09:42 +05304499static int
4500wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4501 struct wireless_dev *wdev,
4502 void *data, int data_len)
4503{
4504 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4505 uint8_t i, feature_sets, max_feature_sets;
4506 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4507 struct sk_buff *reply_skb;
4508
4509 ENTER();
4510
4511 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4512 data, data_len, NULL)) {
4513 hddLog(LOGE, FL("Invalid ATTR"));
4514 return -EINVAL;
4515 }
4516
4517 /* Parse and fetch max feature set */
4518 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4519 hddLog(LOGE, FL("Attr max feature set size failed"));
4520 return -EINVAL;
4521 }
4522 max_feature_sets = nla_get_u32(
4523 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4524 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4525
4526 /* Fill feature combination matrix */
4527 feature_sets = 0;
4528 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4529 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4530 WIFI_FEATURE_P2P;
4531
4532 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4533 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4534 WIFI_FEATURE_SOFT_AP;
4535
4536 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4537 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4538 WIFI_FEATURE_SOFT_AP;
4539
4540 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4541 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4542 WIFI_FEATURE_SOFT_AP |
4543 WIFI_FEATURE_P2P;
4544
4545 /* Add more feature combinations here */
4546
4547 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4548 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4549 hddLog(LOG1, "Feature set matrix");
4550 for (i = 0; i < feature_sets; i++)
4551 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4552
4553 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4554 sizeof(u32) * feature_sets +
4555 NLMSG_HDRLEN);
4556
4557 if (reply_skb) {
4558 if (nla_put_u32(reply_skb,
4559 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4560 feature_sets) ||
4561 nla_put(reply_skb,
4562 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4563 sizeof(u32) * feature_sets, feature_set_matrix)) {
4564 hddLog(LOGE, FL("nla put fail"));
4565 kfree_skb(reply_skb);
4566 return -EINVAL;
4567 }
4568
4569 return cfg80211_vendor_cmd_reply(reply_skb);
4570 }
4571 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4572 return -ENOMEM;
4573
4574max_buffer_err:
4575 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4576 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4577 return -EINVAL;
4578}
4579
Agarwal Ashish518eb3d2014-09-25 12:27:56 +05304580static const struct nla_policy
4581wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4582 +1] =
4583{
4584 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4585};
4586
4587static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4588 struct wireless_dev *wdev,
4589 void *data,
4590 int data_len)
4591{
4592 struct net_device *dev = wdev->netdev;
4593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4594 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4595 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4596 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4597 eHalStatus status;
4598 u32 dfsFlag = 0;
4599
4600 status = wlan_hdd_validate_context(pHddCtx);
4601 if (0 != status) {
4602 hddLog(VOS_TRACE_LEVEL_ERROR,
4603 FL("HDD context is not valid"));
4604 return -EINVAL;
4605 }
4606 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4607 data, data_len,
4608 wlan_hdd_set_no_dfs_flag_config_policy)) {
4609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4610 return -EINVAL;
4611 }
4612
4613 /* Parse and fetch required bandwidth kbps */
4614 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4616 return -EINVAL;
4617 }
4618
4619 dfsFlag = nla_get_u32(
4620 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4621 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4622 dfsFlag);
4623
4624 pHddCtx->disable_dfs_flag = dfsFlag;
4625
4626 sme_disable_dfs_channel(hHal, dfsFlag);
4627 sme_FilterScanResults(hHal, pAdapter->sessionId);
4628 return 0;
4629}
Atul Mittal115287b2014-07-08 13:26:33 +05304630
Mukul Sharma37b4e462014-10-13 14:59:01 +05304631const struct
4632nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4633{
4634 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4635 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4636};
4637
4638static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
4639 struct wireless_dev *wdev, void *data, int data_len)
4640{
4641
4642 u8 bssid[6] = {0};
4643 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4644 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4645 eHalStatus status = eHAL_STATUS_SUCCESS;
4646 v_U32_t isFwrRoamEnabled = FALSE;
4647 int ret;
4648
4649 if (NULL == pHddCtx) {
4650 hddLog(VOS_TRACE_LEVEL_ERROR,
4651 FL("HDD context is not valid"));
4652 return -EINVAL;
4653 }
4654
4655 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4656 data, data_len,
4657 qca_wlan_vendor_attr);
4658 if (ret){
4659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4660 return -EINVAL;
4661 }
4662
4663 /* Parse and fetch Enable flag */
4664 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4666 return -EINVAL;
4667 }
4668
4669 isFwrRoamEnabled = nla_get_u32(
4670 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4671
4672 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4673
4674 /* Parse and fetch bssid */
4675 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4677 return -EINVAL;
4678 }
4679
4680 memcpy(bssid, nla_data(
4681 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4682 sizeof(bssid));
4683 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4684
4685 //Update roaming
4686 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4687 return status;
4688}
4689
Sunil Duttc69bccb2014-05-26 21:30:20 +05304690const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4691{
Mukul Sharma37b4e462014-10-13 14:59:01 +05304692 {
4693 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4694 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4695 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4696 WIPHY_VENDOR_CMD_NEED_NETDEV |
4697 WIPHY_VENDOR_CMD_NEED_RUNNING,
4698 .doit = wlan_hdd_cfg80211_firmware_roaming
4699 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304700#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4701 {
4702 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4703 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4704 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4705 WIPHY_VENDOR_CMD_NEED_NETDEV |
4706 WIPHY_VENDOR_CMD_NEED_RUNNING,
4707 .doit = wlan_hdd_cfg80211_ll_stats_clear
4708 },
4709
4710 {
4711 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4712 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4713 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4714 WIPHY_VENDOR_CMD_NEED_NETDEV |
4715 WIPHY_VENDOR_CMD_NEED_RUNNING,
4716 .doit = wlan_hdd_cfg80211_ll_stats_set
4717 },
4718
4719 {
4720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4723 WIPHY_VENDOR_CMD_NEED_NETDEV |
4724 WIPHY_VENDOR_CMD_NEED_RUNNING,
4725 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304726 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304727#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304728#ifdef WLAN_FEATURE_EXTSCAN
4729 {
4730 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4731 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4732 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4733 WIPHY_VENDOR_CMD_NEED_NETDEV |
4734 WIPHY_VENDOR_CMD_NEED_RUNNING,
4735 .doit = wlan_hdd_cfg80211_extscan_start
4736 },
4737 {
4738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4741 WIPHY_VENDOR_CMD_NEED_NETDEV |
4742 WIPHY_VENDOR_CMD_NEED_RUNNING,
4743 .doit = wlan_hdd_cfg80211_extscan_stop
4744 },
4745 {
4746 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4747 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4748 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4749 WIPHY_VENDOR_CMD_NEED_NETDEV,
4750 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
4751 },
4752 {
4753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4756 WIPHY_VENDOR_CMD_NEED_NETDEV |
4757 WIPHY_VENDOR_CMD_NEED_RUNNING,
4758 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
4759 },
4760 {
4761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4764 WIPHY_VENDOR_CMD_NEED_NETDEV |
4765 WIPHY_VENDOR_CMD_NEED_RUNNING,
4766 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
4767 },
4768 {
4769 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4770 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4771 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4772 WIPHY_VENDOR_CMD_NEED_NETDEV |
4773 WIPHY_VENDOR_CMD_NEED_RUNNING,
4774 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
4775 },
4776 {
4777 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4778 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4779 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4780 WIPHY_VENDOR_CMD_NEED_NETDEV |
4781 WIPHY_VENDOR_CMD_NEED_RUNNING,
4782 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
4783 },
4784 {
4785 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4786 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4787 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4788 WIPHY_VENDOR_CMD_NEED_NETDEV |
4789 WIPHY_VENDOR_CMD_NEED_RUNNING,
4790 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
4791 },
4792 {
4793 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4794 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4795 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4796 WIPHY_VENDOR_CMD_NEED_NETDEV |
4797 WIPHY_VENDOR_CMD_NEED_RUNNING,
4798 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
4799 },
4800#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304801/*EXT TDLS*/
4802 {
4803 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4804 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4805 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4806 WIPHY_VENDOR_CMD_NEED_NETDEV |
4807 WIPHY_VENDOR_CMD_NEED_RUNNING,
4808 .doit = wlan_hdd_cfg80211_exttdls_enable
4809 },
4810 {
4811 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4812 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4813 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4814 WIPHY_VENDOR_CMD_NEED_NETDEV |
4815 WIPHY_VENDOR_CMD_NEED_RUNNING,
4816 .doit = wlan_hdd_cfg80211_exttdls_disable
4817 },
4818 {
4819 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4820 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4821 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4822 WIPHY_VENDOR_CMD_NEED_NETDEV,
4823 .doit = wlan_hdd_cfg80211_exttdls_get_status
4824 },
Dasari Srinivasf70e8fc2014-09-26 17:50:57 +05304825 {
4826 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4827 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4828 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4829 WIPHY_VENDOR_CMD_NEED_NETDEV,
4830 .doit = wlan_hdd_cfg80211_get_supported_features
4831 },
Agarwal Ashish518eb3d2014-09-25 12:27:56 +05304832 {
4833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4836 WIPHY_VENDOR_CMD_NEED_NETDEV,
4837 .doit = wlan_hdd_cfg80211_disable_dfs_channels
4838 },
Siddharth Bhal2a73cfd2014-09-29 21:13:13 +05304839 {
4840 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4841 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4842 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4843 WIPHY_VENDOR_CMD_NEED_NETDEV,
4844 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
4845 },
Dasari Srinivasbee4dce2014-10-28 17:09:42 +05304846 {
4847 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4848 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4849 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4850 WIPHY_VENDOR_CMD_NEED_NETDEV,
4851 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
4852 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304853};
4854
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004855/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304856static const
4857struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004858{
4859#ifdef FEATURE_WLAN_CH_AVOID
4860 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304861 .vendor_id = QCA_NL80211_VENDOR_ID,
4862 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004863 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304864#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4865#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4866 {
4867 /* Index = 1*/
4868 .vendor_id = QCA_NL80211_VENDOR_ID,
4869 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4870 },
4871 {
4872 /* Index = 2*/
4873 .vendor_id = QCA_NL80211_VENDOR_ID,
4874 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4875 },
4876 {
4877 /* Index = 3*/
4878 .vendor_id = QCA_NL80211_VENDOR_ID,
4879 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4880 },
4881 {
4882 /* Index = 4*/
4883 .vendor_id = QCA_NL80211_VENDOR_ID,
4884 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4885 },
4886 {
4887 /* Index = 5*/
4888 .vendor_id = QCA_NL80211_VENDOR_ID,
4889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4890 },
4891 {
4892 /* Index = 6*/
4893 .vendor_id = QCA_NL80211_VENDOR_ID,
4894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4895 },
4896#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304897#ifdef WLAN_FEATURE_EXTSCAN
4898 {
4899 .vendor_id = QCA_NL80211_VENDOR_ID,
4900 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4901 },
4902 {
4903 .vendor_id = QCA_NL80211_VENDOR_ID,
4904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4905 },
4906 {
4907 .vendor_id = QCA_NL80211_VENDOR_ID,
4908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4909 },
4910 {
4911 .vendor_id = QCA_NL80211_VENDOR_ID,
4912 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4913 },
4914 {
4915 .vendor_id = QCA_NL80211_VENDOR_ID,
4916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4917 },
4918 {
4919 .vendor_id = QCA_NL80211_VENDOR_ID,
4920 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4921 },
4922 {
4923 .vendor_id = QCA_NL80211_VENDOR_ID,
4924 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4925 },
4926 {
4927 .vendor_id = QCA_NL80211_VENDOR_ID,
4928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4929 },
4930 {
4931 .vendor_id = QCA_NL80211_VENDOR_ID,
4932 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4933 },
4934 {
4935 .vendor_id = QCA_NL80211_VENDOR_ID,
4936 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4937 },
4938 {
4939 .vendor_id = QCA_NL80211_VENDOR_ID,
4940 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4941 },
4942 {
4943 .vendor_id = QCA_NL80211_VENDOR_ID,
4944 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4945 },
4946 {
4947 .vendor_id = QCA_NL80211_VENDOR_ID,
4948 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4949 },
4950#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304951/*EXT TDLS*/
4952 {
4953 .vendor_id = QCA_NL80211_VENDOR_ID,
4954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
4955 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004956};
4957
Jeff Johnson295189b2012-06-20 16:38:30 -07004958/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304959 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304960 * This function is called by hdd_wlan_startup()
4961 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304962 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004963 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304964struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004965{
4966 struct wiphy *wiphy;
4967 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 /*
4969 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 */
4971 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4972
4973 if (!wiphy)
4974 {
4975 /* Print error and jump into err label and free the memory */
4976 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4977 return NULL;
4978 }
4979
Sunil Duttc69bccb2014-05-26 21:30:20 +05304980
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 return wiphy;
4982}
4983
4984/*
4985 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304986 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 * private ioctl to change the band value
4988 */
4989int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4990{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304991 int i, j;
4992 eNVChannelEnabledType channelEnabledState;
4993
Jeff Johnsone7245742012-09-05 17:12:55 -07004994 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304995
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304996 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304998
4999 if (NULL == wiphy->bands[i])
5000 {
5001 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5002 __func__, i);
5003 continue;
5004 }
5005
5006 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5007 {
5008 struct ieee80211_supported_band *band = wiphy->bands[i];
5009
5010 channelEnabledState = vos_nv_getChannelEnabledState(
5011 band->channels[j].hw_value);
5012
5013 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5014 {
Abhishek Singh371f2a22014-11-04 10:52:38 +05305015 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305016 continue;
5017 }
5018 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5019 {
5020 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5021 continue;
5022 }
5023
5024 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5025 NV_CHANNEL_INVALID == channelEnabledState)
5026 {
5027 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5028 }
5029 else if (NV_CHANNEL_DFS == channelEnabledState)
5030 {
5031 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5032 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5033 }
5034 else
5035 {
5036 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5037 |IEEE80211_CHAN_RADAR);
5038 }
5039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005040 }
5041 return 0;
5042}
5043/*
5044 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305045 * This function is called by hdd_wlan_startup()
5046 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 * This function is used to initialize and register wiphy structure.
5048 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305049int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 struct wiphy *wiphy,
5051 hdd_config_t *pCfg
5052 )
5053{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305054 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305055 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5056
Jeff Johnsone7245742012-09-05 17:12:55 -07005057 ENTER();
5058
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 /* Now bind the underlying wlan device with wiphy */
5060 set_wiphy_dev(wiphy, dev);
5061
5062 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005063
Kiet Lam6c583332013-10-14 05:37:09 +05305064#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005065 /* the flag for the other case would be initialzed in
5066 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005067 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305068#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005069
Amar Singhalfddc28c2013-09-05 13:03:40 -07005070 /* This will disable updating of NL channels from passive to
5071 * active if a beacon is received on passive channel. */
5072 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005073
Amar Singhalfddc28c2013-09-05 13:03:40 -07005074
Amar Singhala49cbc52013-10-08 18:37:44 -07005075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005077 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5078 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5079 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005080 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305081 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005082#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005083
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005084#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005085 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005086#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005087 || pCfg->isFastRoamIniFeatureEnabled
5088#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005089#ifdef FEATURE_WLAN_ESE
5090 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005091#endif
5092 )
5093 {
5094 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5095 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005096#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005097#ifdef FEATURE_WLAN_TDLS
5098 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5099 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5100#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305101#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305102 if (pCfg->configPNOScanSupport)
5103 {
5104 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5105 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5106 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5107 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5108 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305109#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005110
Amar Singhalfddc28c2013-09-05 13:03:40 -07005111#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005112 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5113 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005114 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005115 driver need to determine what to do with both
5116 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005117
5118 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005119#else
5120 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005121#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005122
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305123 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5124
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305125 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005126
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305127 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5128
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305130 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005131 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5133 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 | BIT(NL80211_IFTYPE_AP);
5135
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305136 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005137 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5139 if( pCfg->enableMCC )
5140 {
5141 /* Currently, supports up to two channels */
5142 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005143
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305144 if( !pCfg->allowMCCGODiffBI )
5145 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005146
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305147 }
5148 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5149 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005150#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305151 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005152
Jeff Johnson295189b2012-06-20 16:38:30 -07005153 /* Before registering we need to update the ht capabilitied based
5154 * on ini values*/
5155 if( !pCfg->ShortGI20MhzEnable )
5156 {
5157 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5158 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5159 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5160 }
5161
5162 if( !pCfg->ShortGI40MhzEnable )
5163 {
5164 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5165 }
5166
5167 if( !pCfg->nChannelBondingMode5GHz )
5168 {
5169 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5170 }
5171
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305172 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305173 if (true == hdd_is_5g_supported(pHddCtx))
5174 {
5175 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5176 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305177
5178 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5179 {
5180
5181 if (NULL == wiphy->bands[i])
5182 {
5183 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5184 __func__, i);
5185 continue;
5186 }
5187
5188 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5189 {
5190 struct ieee80211_supported_band *band = wiphy->bands[i];
5191
5192 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5193 {
5194 // Enable social channels for P2P
5195 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5196 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5197 else
5198 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5199 continue;
5200 }
5201 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5202 {
5203 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5204 continue;
5205 }
5206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 }
5208 /*Initialise the supported cipher suite details*/
5209 wiphy->cipher_suites = hdd_cipher_suites;
5210 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5211
5212 /*signal strength in mBm (100*dBm) */
5213 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5214
5215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305216 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005217#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005218
Sunil Duttc69bccb2014-05-26 21:30:20 +05305219 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5220 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005221 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5222 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5223
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305224 EXIT();
5225 return 0;
5226}
5227
5228/* In this function we are registering wiphy. */
5229int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5230{
5231 ENTER();
5232 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 if (0 > wiphy_register(wiphy))
5234 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305235 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5237 return -EIO;
5238 }
5239
5240 EXIT();
5241 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242}
Jeff Johnson295189b2012-06-20 16:38:30 -07005243
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305244/* In this function we are updating channel list when,
5245 regulatory domain is FCC and country code is US.
5246 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5247 As per FCC smart phone is not a indoor device.
5248 GO should not opeate on indoor channels */
5249void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5250{
5251 int j;
5252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5253 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5254 //Default counrtycode from NV at the time of wiphy initialization.
5255 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5256 &defaultCountryCode[0]))
5257 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005258 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305259 }
5260 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5261 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305262 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5263 {
5264 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5265 return;
5266 }
5267 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5268 {
5269 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5270 // Mark UNII -1 band channel as passive
5271 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5272 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5273 }
5274 }
5275}
5276
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305277/* This function registers for all frame which supplicant is interested in */
5278void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005279{
Jeff Johnson295189b2012-06-20 16:38:30 -07005280 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5281 /* Register for all P2P action, public action etc frames */
5282 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5283
Jeff Johnsone7245742012-09-05 17:12:55 -07005284 ENTER();
5285
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 /* Right now we are registering these frame when driver is getting
5287 initialized. Once we will move to 2.6.37 kernel, in which we have
5288 frame register ops, we will move this code as a part of that */
5289 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5292
5293 /* GAS Initial Response */
5294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5295 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305296
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 /* GAS Comeback Request */
5298 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5299 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5300
5301 /* GAS Comeback Response */
5302 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5303 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5304
5305 /* P2P Public Action */
5306 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 P2P_PUBLIC_ACTION_FRAME_SIZE );
5309
5310 /* P2P Action */
5311 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5312 (v_U8_t*)P2P_ACTION_FRAME,
5313 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005314
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305315 /* WNM BSS Transition Request frame */
5316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5317 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5318 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005319
5320 /* WNM-Notification */
5321 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5322 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5323 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005324}
5325
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305326void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005327{
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5329 /* Register for all P2P action, public action etc frames */
5330 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5331
Jeff Johnsone7245742012-09-05 17:12:55 -07005332 ENTER();
5333
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 /* Right now we are registering these frame when driver is getting
5335 initialized. Once we will move to 2.6.37 kernel, in which we have
5336 frame register ops, we will move this code as a part of that */
5337 /* GAS Initial Request */
5338
5339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5340 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5341
5342 /* GAS Initial Response */
5343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5344 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305345
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 /* GAS Comeback Request */
5347 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5348 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5349
5350 /* GAS Comeback Response */
5351 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5352 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5353
5354 /* P2P Public Action */
5355 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305356 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 P2P_PUBLIC_ACTION_FRAME_SIZE );
5358
5359 /* P2P Action */
5360 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5361 (v_U8_t*)P2P_ACTION_FRAME,
5362 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005363 /* WNM-Notification */
5364 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5365 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5366 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005367}
5368
5369#ifdef FEATURE_WLAN_WAPI
5370void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5371 const u8 *mac_addr, u8 *key , int key_Len)
5372{
5373 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5374 tCsrRoamSetKey setKey;
5375 v_BOOL_t isConnected = TRUE;
5376 int status = 0;
5377 v_U32_t roamId= 0xFF;
5378 tANI_U8 *pKeyPtr = NULL;
5379 int n = 0;
5380
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305381 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5382 __func__, hdd_device_modetoString(pAdapter->device_mode),
5383 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005384
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305385 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005386 setKey.keyId = key_index; // Store Key ID
5387 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5388 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5389 setKey.paeRole = 0 ; // the PAE role
5390 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5391 {
5392 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5393 }
5394 else
5395 {
5396 isConnected = hdd_connIsConnected(pHddStaCtx);
5397 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5398 }
5399 setKey.keyLength = key_Len;
5400 pKeyPtr = setKey.Key;
5401 memcpy( pKeyPtr, key, key_Len);
5402
Arif Hussain6d2a3322013-11-17 19:50:10 -08005403 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 __func__, key_Len);
5405 for (n = 0 ; n < key_Len; n++)
5406 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5407 __func__,n,setKey.Key[n]);
5408
5409 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5410 if ( isConnected )
5411 {
5412 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5413 pAdapter->sessionId, &setKey, &roamId );
5414 }
5415 if ( status != 0 )
5416 {
5417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5418 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5419 __LINE__, status );
5420 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5421 }
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05305422 /* Need to clear any trace of key value in the memory.
5423 * Thus zero out the memory even though it is local
5424 * variable.
5425 */
5426 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005427}
5428#endif /* FEATURE_WLAN_WAPI*/
5429
5430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305431int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 beacon_data_t **ppBeacon,
5433 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005434#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305435int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005436 beacon_data_t **ppBeacon,
5437 struct cfg80211_beacon_data *params,
5438 int dtim_period)
5439#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440{
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 int size;
5442 beacon_data_t *beacon = NULL;
5443 beacon_data_t *old = NULL;
5444 int head_len,tail_len;
5445
Jeff Johnsone7245742012-09-05 17:12:55 -07005446 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005447 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305448 {
5449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5450 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005453
5454 old = pAdapter->sessionCtx.ap.beacon;
5455
5456 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305457 {
5458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5459 FL("session(%d) old and new heads points to NULL"),
5460 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305462 }
5463
5464 if (params->tail && !params->tail_len)
5465 {
5466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5467 FL("tail_len is zero but tail is not NULL"));
5468 return -EINVAL;
5469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005470
Jeff Johnson295189b2012-06-20 16:38:30 -07005471#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5472 /* Kernel 3.0 is not updating dtim_period for set beacon */
5473 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305474 {
5475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5476 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005479#endif
5480
5481 if(params->head)
5482 head_len = params->head_len;
5483 else
5484 head_len = old->head_len;
5485
5486 if(params->tail || !old)
5487 tail_len = params->tail_len;
5488 else
5489 tail_len = old->tail_len;
5490
5491 size = sizeof(beacon_data_t) + head_len + tail_len;
5492
5493 beacon = kzalloc(size, GFP_KERNEL);
5494
5495 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305496 {
5497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5498 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005501
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005502#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 if(params->dtim_period || !old )
5504 beacon->dtim_period = params->dtim_period;
5505 else
5506 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005507#else
5508 if(dtim_period || !old )
5509 beacon->dtim_period = dtim_period;
5510 else
5511 beacon->dtim_period = old->dtim_period;
5512#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5515 beacon->tail = beacon->head + head_len;
5516 beacon->head_len = head_len;
5517 beacon->tail_len = tail_len;
5518
5519 if(params->head) {
5520 memcpy (beacon->head,params->head,beacon->head_len);
5521 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305522 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 if(old)
5524 memcpy (beacon->head,old->head,beacon->head_len);
5525 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305526
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 if(params->tail) {
5528 memcpy (beacon->tail,params->tail,beacon->tail_len);
5529 }
5530 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 memcpy (beacon->tail,old->tail,beacon->tail_len);
5533 }
5534
5535 *ppBeacon = beacon;
5536
5537 kfree(old);
5538
5539 return 0;
5540
5541}
Jeff Johnson295189b2012-06-20 16:38:30 -07005542
5543v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5544{
5545 int left = length;
5546 v_U8_t *ptr = pIes;
5547 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305548
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305550 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 elem_id = ptr[0];
5552 elem_len = ptr[1];
5553 left -= 2;
5554 if(elem_len > left)
5555 {
5556 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005557 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 eid,elem_len,left);
5559 return NULL;
5560 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305561 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 {
5563 return ptr;
5564 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305565
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 left -= elem_len;
5567 ptr += (elem_len + 2);
5568 }
5569 return NULL;
5570}
5571
Jeff Johnson295189b2012-06-20 16:38:30 -07005572/* Check if rate is 11g rate or not */
5573static int wlan_hdd_rate_is_11g(u8 rate)
5574{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005575 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 u8 i;
5577 for (i = 0; i < 8; i++)
5578 {
5579 if(rate == gRateArray[i])
5580 return TRUE;
5581 }
5582 return FALSE;
5583}
5584
5585/* Check for 11g rate and set proper 11g only mode */
5586static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5587 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5588{
5589 u8 i, num_rates = pIe[0];
5590
5591 pIe += 1;
5592 for ( i = 0; i < num_rates; i++)
5593 {
5594 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5595 {
5596 /* If rate set have 11g rate than change the mode to 11G */
5597 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5598 if (pIe[i] & BASIC_RATE_MASK)
5599 {
5600 /* If we have 11g rate as basic rate, it means mode
5601 is 11g only mode.
5602 */
5603 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5604 *pCheckRatesfor11g = FALSE;
5605 }
5606 }
5607 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5608 {
5609 *require_ht = TRUE;
5610 }
5611 }
5612 return;
5613}
5614
5615static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5616{
5617 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5618 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5619 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5620 u8 checkRatesfor11g = TRUE;
5621 u8 require_ht = FALSE;
5622 u8 *pIe=NULL;
5623
5624 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5625
5626 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5627 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5628 if (pIe != NULL)
5629 {
5630 pIe += 1;
5631 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5632 &pConfig->SapHw_mode);
5633 }
5634
5635 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5636 WLAN_EID_EXT_SUPP_RATES);
5637 if (pIe != NULL)
5638 {
5639
5640 pIe += 1;
5641 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5642 &pConfig->SapHw_mode);
5643 }
5644
5645 if( pConfig->channel > 14 )
5646 {
5647 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5648 }
5649
5650 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5651 WLAN_EID_HT_CAPABILITY);
5652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305653 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005654 {
5655 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5656 if(require_ht)
5657 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5658 }
5659}
5660
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305661static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5662 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5663{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005664 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305665 v_U8_t *pIe = NULL;
5666 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5667
5668 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5669 pBeacon->tail, pBeacon->tail_len);
5670
5671 if (pIe)
5672 {
5673 ielen = pIe[1] + 2;
5674 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5675 {
5676 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5677 }
5678 else
5679 {
5680 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5681 return -EINVAL;
5682 }
5683 *total_ielen += ielen;
5684 }
5685 return 0;
5686}
5687
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005688static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5689 v_U8_t *genie, v_U8_t *total_ielen)
5690{
5691 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5692 int left = pBeacon->tail_len;
5693 v_U8_t *ptr = pBeacon->tail;
5694 v_U8_t elem_id, elem_len;
5695 v_U16_t ielen = 0;
5696
5697 if ( NULL == ptr || 0 == left )
5698 return;
5699
5700 while (left >= 2)
5701 {
5702 elem_id = ptr[0];
5703 elem_len = ptr[1];
5704 left -= 2;
5705 if (elem_len > left)
5706 {
5707 hddLog( VOS_TRACE_LEVEL_ERROR,
5708 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5709 elem_id, elem_len, left);
5710 return;
5711 }
5712 if (IE_EID_VENDOR == elem_id)
5713 {
5714 /* skipping the VSIE's which we don't want to include or
5715 * it will be included by existing code
5716 */
5717 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5718#ifdef WLAN_FEATURE_WFD
5719 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5720#endif
5721 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5722 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5723 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5724 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5725 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5726 {
5727 ielen = ptr[1] + 2;
5728 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5729 {
5730 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5731 *total_ielen += ielen;
5732 }
5733 else
5734 {
5735 hddLog( VOS_TRACE_LEVEL_ERROR,
5736 "IE Length is too big "
5737 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5738 elem_id, elem_len, *total_ielen);
5739 }
5740 }
5741 }
5742
5743 left -= elem_len;
5744 ptr += (elem_len + 2);
5745 }
5746 return;
5747}
5748
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005749#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005750static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5751 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005752#else
5753static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5754 struct cfg80211_beacon_data *params)
5755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005756{
5757 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305758 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005760 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005761
5762 genie = vos_mem_malloc(MAX_GENIE_LEN);
5763
5764 if(genie == NULL) {
5765
5766 return -ENOMEM;
5767 }
5768
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305769 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5770 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305772 hddLog(LOGE,
5773 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305774 ret = -EINVAL;
5775 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 }
5777
5778#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305779 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5780 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5781 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305782 hddLog(LOGE,
5783 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305784 ret = -EINVAL;
5785 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 }
5787#endif
5788
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305789 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5790 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305792 hddLog(LOGE,
5793 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305794 ret = -EINVAL;
5795 goto done;
5796 }
5797
5798 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5799 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005800 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005802
5803 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5804 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5805 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5806 {
5807 hddLog(LOGE,
5808 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005809 ret = -EINVAL;
5810 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 }
5812
5813 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5814 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5815 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5816 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5817 ==eHAL_STATUS_FAILURE)
5818 {
5819 hddLog(LOGE,
5820 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005821 ret = -EINVAL;
5822 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 }
5824
5825 // Added for ProResp IE
5826 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5827 {
5828 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5829 u8 probe_rsp_ie_len[3] = {0};
5830 u8 counter = 0;
5831 /* Check Probe Resp Length if it is greater then 255 then Store
5832 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5833 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5834 Store More then 255 bytes into One Variable.
5835 */
5836 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5837 {
5838 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5839 {
5840 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5841 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5842 }
5843 else
5844 {
5845 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5846 rem_probe_resp_ie_len = 0;
5847 }
5848 }
5849
5850 rem_probe_resp_ie_len = 0;
5851
5852 if (probe_rsp_ie_len[0] > 0)
5853 {
5854 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5855 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5856 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5857 probe_rsp_ie_len[0], NULL,
5858 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5859 {
5860 hddLog(LOGE,
5861 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005862 ret = -EINVAL;
5863 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 }
5865 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5866 }
5867
5868 if (probe_rsp_ie_len[1] > 0)
5869 {
5870 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5871 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5872 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5873 probe_rsp_ie_len[1], NULL,
5874 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5875 {
5876 hddLog(LOGE,
5877 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005878 ret = -EINVAL;
5879 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 }
5881 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5882 }
5883
5884 if (probe_rsp_ie_len[2] > 0)
5885 {
5886 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5887 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5888 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5889 probe_rsp_ie_len[2], NULL,
5890 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5891 {
5892 hddLog(LOGE,
5893 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005894 ret = -EINVAL;
5895 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 }
5897 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5898 }
5899
5900 if (probe_rsp_ie_len[1] == 0 )
5901 {
5902 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5903 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5904 eANI_BOOLEAN_FALSE) )
5905 {
5906 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005907 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 }
5909 }
5910
5911 if (probe_rsp_ie_len[2] == 0 )
5912 {
5913 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5914 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5915 eANI_BOOLEAN_FALSE) )
5916 {
5917 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005918 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 }
5920 }
5921
5922 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5923 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5924 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5925 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5926 == eHAL_STATUS_FAILURE)
5927 {
5928 hddLog(LOGE,
5929 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005930 ret = -EINVAL;
5931 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 }
5933 }
5934 else
5935 {
5936 // Reset WNI_CFG_PROBE_RSP Flags
5937 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5938
5939 hddLog(VOS_TRACE_LEVEL_INFO,
5940 "%s: No Probe Response IE received in set beacon",
5941 __func__);
5942 }
5943
5944 // Added for AssocResp IE
5945 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5946 {
5947 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5948 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5949 params->assocresp_ies_len, NULL,
5950 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5951 {
5952 hddLog(LOGE,
5953 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005954 ret = -EINVAL;
5955 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 }
5957
5958 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5959 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5960 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5961 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5962 == eHAL_STATUS_FAILURE)
5963 {
5964 hddLog(LOGE,
5965 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005966 ret = -EINVAL;
5967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 }
5969 }
5970 else
5971 {
5972 hddLog(VOS_TRACE_LEVEL_INFO,
5973 "%s: No Assoc Response IE received in set beacon",
5974 __func__);
5975
5976 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5977 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5978 eANI_BOOLEAN_FALSE) )
5979 {
5980 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005981 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 }
5983 }
5984
Jeff Johnsone7245742012-09-05 17:12:55 -07005985done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305987 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005988}
Jeff Johnson295189b2012-06-20 16:38:30 -07005989
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 * FUNCTION: wlan_hdd_validate_operation_channel
5992 * called by wlan_hdd_cfg80211_start_bss() and
5993 * wlan_hdd_cfg80211_set_channel()
5994 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305995 * channel list.
5996 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005997VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005998{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305999
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 v_U32_t num_ch = 0;
6001 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6002 u32 indx = 0;
6003 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306004 v_U8_t fValidChannel = FALSE, count = 0;
6005 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6008
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306009 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306011 /* Validate the channel */
6012 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306014 if ( channel == rfChannels[count].channelNum )
6015 {
6016 fValidChannel = TRUE;
6017 break;
6018 }
6019 }
6020 if (fValidChannel != TRUE)
6021 {
6022 hddLog(VOS_TRACE_LEVEL_ERROR,
6023 "%s: Invalid Channel [%d]", __func__, channel);
6024 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006025 }
6026 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306027 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306029 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6030 valid_ch, &num_ch))
6031 {
6032 hddLog(VOS_TRACE_LEVEL_ERROR,
6033 "%s: failed to get valid channel list", __func__);
6034 return VOS_STATUS_E_FAILURE;
6035 }
6036 for (indx = 0; indx < num_ch; indx++)
6037 {
6038 if (channel == valid_ch[indx])
6039 {
6040 break;
6041 }
6042 }
6043
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306044 if (indx >= num_ch)
6045 {
6046 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6047 {
6048 eCsrBand band;
6049 unsigned int freq;
6050
6051 sme_GetFreqBand(hHal, &band);
6052
6053 if (eCSR_BAND_5G == band)
6054 {
6055#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6056 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6057 {
6058 freq = ieee80211_channel_to_frequency(channel,
6059 IEEE80211_BAND_2GHZ);
6060 }
6061 else
6062 {
6063 freq = ieee80211_channel_to_frequency(channel,
6064 IEEE80211_BAND_5GHZ);
6065 }
6066#else
6067 freq = ieee80211_channel_to_frequency(channel);
6068#endif
6069 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6070 return VOS_STATUS_SUCCESS;
6071 }
6072 }
6073
6074 hddLog(VOS_TRACE_LEVEL_ERROR,
6075 "%s: Invalid Channel [%d]", __func__, channel);
6076 return VOS_STATUS_E_FAILURE;
6077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306079
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306081
Jeff Johnson295189b2012-06-20 16:38:30 -07006082}
6083
Viral Modi3a32cc52013-02-08 11:14:52 -08006084/**
6085 * FUNCTION: wlan_hdd_cfg80211_set_channel
6086 * This function is used to set the channel number
6087 */
6088static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
6089 struct ieee80211_channel *chan,
6090 enum nl80211_channel_type channel_type
6091 )
6092{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306093 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006094 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006095 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006096 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306097 hdd_context_t *pHddCtx;
6098 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006099
6100 ENTER();
6101
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306102
Viral Modi3a32cc52013-02-08 11:14:52 -08006103 if( NULL == dev )
6104 {
6105 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006106 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006107 return -ENODEV;
6108 }
6109 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306110
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306111 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6112 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6113 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006114 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306115 "%s: device_mode = %s (%d) freq = %d", __func__,
6116 hdd_device_modetoString(pAdapter->device_mode),
6117 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306118
6119 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6120 status = wlan_hdd_validate_context(pHddCtx);
6121
6122 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006123 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6125 "%s: HDD context is not valid", __func__);
6126 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006127 }
6128
6129 /*
6130 * Do freq to chan conversion
6131 * TODO: for 11a
6132 */
6133
6134 channel = ieee80211_frequency_to_channel(freq);
6135
6136 /* Check freq range */
6137 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6138 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6139 {
6140 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006141 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006142 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6143 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6144 return -EINVAL;
6145 }
6146
6147 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6148
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306149 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6150 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006151 {
6152 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6153 {
6154 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006155 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006156 return -EINVAL;
6157 }
6158 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6159 "%s: set channel to [%d] for device mode =%d",
6160 __func__, channel,pAdapter->device_mode);
6161 }
6162 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006163 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006164 )
6165 {
6166 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6167 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6168 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6169
6170 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6171 {
6172 /* Link is up then return cant set channel*/
6173 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006174 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006175 return -EINVAL;
6176 }
6177
6178 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6179 pHddStaCtx->conn_info.operationChannel = channel;
6180 pRoamProfile->ChannelInfo.ChannelList =
6181 &pHddStaCtx->conn_info.operationChannel;
6182 }
6183 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006184 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006185 )
6186 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306187 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6188 {
6189 if(VOS_STATUS_SUCCESS !=
6190 wlan_hdd_validate_operation_channel(pAdapter,channel))
6191 {
6192 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006193 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306194 return -EINVAL;
6195 }
6196 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6197 }
6198 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006199 {
6200 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6201
6202 /* If auto channel selection is configured as enable/ 1 then ignore
6203 channel set by supplicant
6204 */
6205 if ( cfg_param->apAutoChannelSelection )
6206 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306207 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6208 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006209 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306210 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6211 __func__, hdd_device_modetoString(pAdapter->device_mode),
6212 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006213 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306214 else
6215 {
6216 if(VOS_STATUS_SUCCESS !=
6217 wlan_hdd_validate_operation_channel(pAdapter,channel))
6218 {
6219 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006220 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306221 return -EINVAL;
6222 }
6223 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6224 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006225 }
6226 }
6227 else
6228 {
6229 hddLog(VOS_TRACE_LEVEL_FATAL,
6230 "%s: Invalid device mode failed to set valid channel", __func__);
6231 return -EINVAL;
6232 }
6233 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306234 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006235}
6236
Jeff Johnson295189b2012-06-20 16:38:30 -07006237#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6238static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6239 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006240#else
6241static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6242 struct cfg80211_beacon_data *params,
6243 const u8 *ssid, size_t ssid_len,
6244 enum nl80211_hidden_ssid hidden_ssid)
6245#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006246{
6247 tsap_Config_t *pConfig;
6248 beacon_data_t *pBeacon = NULL;
6249 struct ieee80211_mgmt *pMgmt_frame;
6250 v_U8_t *pIe=NULL;
6251 v_U16_t capab_info;
6252 eCsrAuthType RSNAuthType;
6253 eCsrEncryptionType RSNEncryptType;
6254 eCsrEncryptionType mcRSNEncryptType;
6255 int status = VOS_STATUS_SUCCESS;
6256 tpWLAN_SAPEventCB pSapEventCallback;
6257 hdd_hostapd_state_t *pHostapdState;
6258 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6259 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306260 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306262 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006264 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu4c717bd2014-09-05 17:21:18 +05306265 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006266 v_BOOL_t MFPCapable = VOS_FALSE;
6267 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306268 eHddDot11Mode sapDot11Mode =
6269 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006270
6271 ENTER();
6272
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306273 iniConfig = pHddCtx->cfg_ini;
6274
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6276
6277 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6278
6279 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6280
6281 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6282
6283 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6284
6285 //channel is already set in the set_channel Call back
6286 //pConfig->channel = pCommitConfig->channel;
6287
6288 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6291
6292 pConfig->dtim_period = pBeacon->dtim_period;
6293
Arif Hussain6d2a3322013-11-17 19:50:10 -08006294 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 pConfig->dtim_period);
6296
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006297 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006298 {
6299 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306301 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6302 {
6303 tANI_BOOLEAN restartNeeded;
6304 pConfig->ieee80211d = 1;
6305 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6306 sme_setRegInfo(hHal, pConfig->countryCode);
6307 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6308 }
6309 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006311 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006312 pConfig->ieee80211d = 1;
6313 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6314 sme_setRegInfo(hHal, pConfig->countryCode);
6315 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006317 else
6318 {
6319 pConfig->ieee80211d = 0;
6320 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306321 /*
6322 * If auto channel is configured i.e. channel is 0,
6323 * so skip channel validation.
6324 */
6325 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6326 {
6327 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6328 {
6329 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006330 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306331 return -EINVAL;
6332 }
6333 }
6334 else
6335 {
6336 if(1 != pHddCtx->is_dynamic_channel_range_set)
6337 {
6338 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6339 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6340 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6341 }
6342 pHddCtx->is_dynamic_channel_range_set = 0;
6343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006345 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 {
6347 pConfig->ieee80211d = 0;
6348 }
6349 pConfig->authType = eSAP_AUTO_SWITCH;
6350
6351 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306352
6353 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6355
6356 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6357
6358 /*Set wps station to configured*/
6359 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6360
6361 if(pIe)
6362 {
6363 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6364 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006365 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 return -EINVAL;
6367 }
6368 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6369 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006370 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 /* Check 15 bit of WPS IE as it contain information for wps state
6372 * WPS state
6373 */
6374 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6375 {
6376 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6377 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6378 {
6379 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6380 }
6381 }
6382 }
6383 else
6384 {
6385 pConfig->wps_state = SAP_WPS_DISABLED;
6386 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306387 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006388
c_hpothufe599e92014-06-16 11:38:55 +05306389 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6390 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6391 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6392 eCSR_ENCRYPT_TYPE_NONE;
6393
Jeff Johnson295189b2012-06-20 16:38:30 -07006394 pConfig->RSNWPAReqIELength = 0;
6395 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 WLAN_EID_RSN);
6398 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306399 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6401 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6402 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306403 /* The actual processing may eventually be more extensive than
6404 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 * by the app.
6406 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306407 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6409 &RSNEncryptType,
6410 &mcRSNEncryptType,
6411 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006412 &MFPCapable,
6413 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 pConfig->pRSNWPAReqIE[1]+2,
6415 pConfig->pRSNWPAReqIE );
6416
6417 if( VOS_STATUS_SUCCESS == status )
6418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306419 /* Now copy over all the security attributes you have
6420 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 * */
6422 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6423 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6424 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6425 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306426 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006427 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6429 }
6430 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306431
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6433 pBeacon->tail, pBeacon->tail_len);
6434
6435 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6436 {
6437 if (pConfig->pRSNWPAReqIE)
6438 {
6439 /*Mixed mode WPA/WPA2*/
6440 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6441 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6442 }
6443 else
6444 {
6445 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6446 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6447 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306448 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6450 &RSNEncryptType,
6451 &mcRSNEncryptType,
6452 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006453 &MFPCapable,
6454 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 pConfig->pRSNWPAReqIE[1]+2,
6456 pConfig->pRSNWPAReqIE );
6457
6458 if( VOS_STATUS_SUCCESS == status )
6459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306460 /* Now copy over all the security attributes you have
6461 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 * */
6463 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6464 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6465 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6466 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306467 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006468 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6470 }
6471 }
6472 }
6473
Jeff Johnson4416a782013-03-25 14:17:50 -07006474 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6475 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6476 return -EINVAL;
6477 }
6478
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6480
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006481#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 if (params->ssid != NULL)
6483 {
6484 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6485 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6486 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6487 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6488 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006489#else
6490 if (ssid != NULL)
6491 {
6492 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6493 pConfig->SSIDinfo.ssid.length = ssid_len;
6494 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6495 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6496 }
6497#endif
6498
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306499 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306501
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 /* default value */
6503 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6504 pConfig->num_accept_mac = 0;
6505 pConfig->num_deny_mac = 0;
6506
6507 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6508 pBeacon->tail, pBeacon->tail_len);
6509
6510 /* pIe for black list is following form:
6511 type : 1 byte
6512 length : 1 byte
6513 OUI : 4 bytes
6514 acl type : 1 byte
6515 no of mac addr in black list: 1 byte
6516 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306517 */
6518 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 {
6520 pConfig->SapMacaddr_acl = pIe[6];
6521 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006522 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306524 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6525 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6527 for (i = 0; i < pConfig->num_deny_mac; i++)
6528 {
6529 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6530 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 }
6533 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6534 pBeacon->tail, pBeacon->tail_len);
6535
6536 /* pIe for white list is following form:
6537 type : 1 byte
6538 length : 1 byte
6539 OUI : 4 bytes
6540 acl type : 1 byte
6541 no of mac addr in white list: 1 byte
6542 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306543 */
6544 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 {
6546 pConfig->SapMacaddr_acl = pIe[6];
6547 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006548 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306550 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6551 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6553 for (i = 0; i < pConfig->num_accept_mac; i++)
6554 {
6555 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6556 acl_entry++;
6557 }
6558 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306559
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6561
Jeff Johnsone7245742012-09-05 17:12:55 -07006562#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006563 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306564 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6565 * 11ac in .ini and 11ac is supported by both host and firmware.
6566 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6567 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006568 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6569 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306570 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6571 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6572 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6573 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6574 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006575 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306576 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006577 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306578 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006579
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306580 /* If ACS disable and selected channel <= 14
6581 * OR
6582 * ACS enabled and ACS operating band is choosen as 2.4
6583 * AND
6584 * VHT in 2.4G Disabled
6585 * THEN
6586 * Fallback to 11N mode
6587 */
6588 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6589 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri31ee4c42014-10-13 17:02:29 +05306590 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306591 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006592 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306593 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6594 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006595 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6596 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006597 }
6598#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306599
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07006600 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
6601 {
6602 sme_SelectCBMode(hHal,
6603 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
6604 pConfig->channel);
6605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 // ht_capab is not what the name conveys,this is used for protection bitmap
6607 pConfig->ht_capab =
6608 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6609
6610 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6611 {
6612 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6613 return -EINVAL;
6614 }
6615
6616 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6619 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306620 pConfig->obssProtEnabled =
6621 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006622
Chet Lanctot8cecea22014-02-11 19:09:36 -08006623#ifdef WLAN_FEATURE_11W
6624 pConfig->mfpCapable = MFPCapable;
6625 pConfig->mfpRequired = MFPRequired;
6626 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6627 pConfig->mfpCapable, pConfig->mfpRequired);
6628#endif
6629
Arif Hussain6d2a3322013-11-17 19:50:10 -08006630 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006632 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6633 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6634 (int)pConfig->channel);
6635 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6636 pConfig->SapHw_mode, pConfig->privacy,
6637 pConfig->authType);
6638 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6639 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6640 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6641 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006642
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306643 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 {
6645 //Bss already started. just return.
6646 //TODO Probably it should update some beacon params.
6647 hddLog( LOGE, "Bss Already started...Ignore the request");
6648 EXIT();
6649 return 0;
6650 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306651
Agarwal Ashish51325b52014-06-16 16:50:49 +05306652 if (vos_max_concurrent_connections_reached()) {
6653 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6654 return -EINVAL;
6655 }
6656
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 pConfig->persona = pHostapdAdapter->device_mode;
6658
Peng Xu4c717bd2014-09-05 17:21:18 +05306659 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6660 if ( NULL != psmeConfig)
6661 {
6662 sme_GetConfigParam(hHal, psmeConfig);
6663 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
6664 vos_mem_free(psmeConfig);
6665 }
Peng Xua4cfb9f2014-09-25 13:23:55 +05306666 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu4c717bd2014-09-05 17:21:18 +05306667
Jeff Johnson295189b2012-06-20 16:38:30 -07006668 pSapEventCallback = hdd_hostapd_SAPEventCB;
6669 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6670 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6671 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006672 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 return -EINVAL;
6674 }
6675
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306676 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6678
6679 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306680
Jeff Johnson295189b2012-06-20 16:38:30 -07006681 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682 {
6683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006684 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006685 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 VOS_ASSERT(0);
6687 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306688
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantee5653e2014-10-15 15:09:23 +05306690 /* Initialize WMM configuation */
6691 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306692 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006693
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006694#ifdef WLAN_FEATURE_P2P_DEBUG
6695 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6696 {
6697 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6698 {
6699 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6700 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006701 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006702 }
6703 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6704 {
6705 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6706 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006707 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006708 }
6709 }
6710#endif
6711
Jeff Johnson295189b2012-06-20 16:38:30 -07006712 pHostapdState->bCommit = TRUE;
6713 EXIT();
6714
6715 return 0;
6716}
6717
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006718#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
mukul sharma1cfb0682014-12-15 18:58:53 +05306719static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306720 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 struct beacon_parameters *params)
6722{
6723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306724 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306725 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006726
6727 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306728
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306729 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6730 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6731 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306732 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6733 hdd_device_modetoString(pAdapter->device_mode),
6734 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006735
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306736 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6737 status = wlan_hdd_validate_context(pHddCtx);
6738
6739 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006740 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6742 "%s: HDD context is not valid", __func__);
6743 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006744 }
6745
Agarwal Ashish51325b52014-06-16 16:50:49 +05306746 if (vos_max_concurrent_connections_reached()) {
6747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6748 return -EINVAL;
6749 }
6750
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306751 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 )
6754 {
6755 beacon_data_t *old,*new;
6756
6757 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306758
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306760 {
6761 hddLog(VOS_TRACE_LEVEL_WARN,
6762 FL("already beacon info added to session(%d)"),
6763 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006766
6767 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6768
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306769 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 {
6771 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006772 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 return -EINVAL;
6774 }
6775
6776 pAdapter->sessionCtx.ap.beacon = new;
6777
6778 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6779 }
6780
6781 EXIT();
6782 return status;
6783}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306784
mukul sharma1cfb0682014-12-15 18:58:53 +05306785static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6786 struct net_device *dev,
6787 struct beacon_parameters *params)
6788{
6789 int ret;
6790
6791 vos_ssr_protect(__func__);
6792 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
6793 vos_ssr_unprotect(__func__);
6794
6795 return ret;
6796}
6797
6798static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 struct net_device *dev,
6800 struct beacon_parameters *params)
6801{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306803 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6804 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306805 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006806
6807 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6809 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6810 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6812 __func__, hdd_device_modetoString(pAdapter->device_mode),
6813 pAdapter->device_mode);
6814
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306815 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6816 status = wlan_hdd_validate_context(pHddCtx);
6817
6818 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6821 "%s: HDD context is not valid", __func__);
6822 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006823 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306824
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306825 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006826 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306827 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 {
6829 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306830
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306832
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306834 {
6835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6836 FL("session(%d) old and new heads points to NULL"),
6837 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306839 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006840
6841 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6842
6843 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306844 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006845 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 return -EINVAL;
6847 }
6848
6849 pAdapter->sessionCtx.ap.beacon = new;
6850
6851 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6852 }
6853
6854 EXIT();
6855 return status;
6856}
6857
mukul sharma1cfb0682014-12-15 18:58:53 +05306858static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
6859 struct net_device *dev,
6860 struct beacon_parameters *params)
6861{
6862 int ret;
6863
6864 vos_ssr_protect(__func__);
6865 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
6866 vos_ssr_unprotect(__func__);
6867
6868 return ret;
6869}
6870
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006871#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6872
6873#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
mukul sharma1cfb0682014-12-15 18:58:53 +05306874static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006876#else
mukul sharma1cfb0682014-12-15 18:58:53 +05306877static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878 struct net_device *dev)
6879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006880{
6881 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006882 hdd_context_t *pHddCtx = NULL;
6883 hdd_scaninfo_t *pScanInfo = NULL;
6884 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306885 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306886 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006887
6888 ENTER();
6889
6890 if (NULL == pAdapter)
6891 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006893 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 return -ENODEV;
6895 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6898 TRACE_CODE_HDD_CFG80211_STOP_AP,
6899 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306900 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6901 status = wlan_hdd_validate_context(pHddCtx);
6902
6903 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006904 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6906 "%s: HDD context is not valid", __func__);
6907 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006908 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006909
6910 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6911 if (NULL == staAdapter)
6912 {
6913 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6914 if (NULL == staAdapter)
6915 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6917 "%s: HDD adapter context for STA/P2P-CLI is Null",
6918 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006919 }
6920 }
6921
6922 pScanInfo = &pHddCtx->scan_info;
6923
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6925 __func__, hdd_device_modetoString(pAdapter->device_mode),
6926 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006927
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306928 ret = wlan_hdd_scan_abort(pAdapter);
6929
Girish Gowli4bf7a632014-06-12 13:42:11 +05306930 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006931 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6933 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306934
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306935 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07006936 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6938 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08006939
Jeff Johnsone7245742012-09-05 17:12:55 -07006940 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306941 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07006942 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306943 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07006944 }
6945
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05306946 /* Delete all associated STAs before stopping AP/P2P GO */
6947 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05306948 hdd_hostapd_stop(dev);
6949
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 )
6953 {
6954 beacon_data_t *old;
6955
6956 old = pAdapter->sessionCtx.ap.beacon;
6957
6958 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306959 {
6960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6961 FL("session(%d) beacon data points to NULL"),
6962 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306964 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006965
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006967
6968 mutex_lock(&pHddCtx->sap_lock);
6969 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6970 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006971 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 {
6973 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6974
6975 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6976
6977 if (!VOS_IS_STATUS_SUCCESS(status))
6978 {
6979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006980 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306982 }
6983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306985 /* BSS stopped, clear the active sessions for this device mode */
6986 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 }
6988 mutex_unlock(&pHddCtx->sap_lock);
6989
6990 if(status != VOS_STATUS_SUCCESS)
6991 {
6992 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006993 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 return -EINVAL;
6995 }
6996
Jeff Johnson4416a782013-03-25 14:17:50 -07006997 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6999 ==eHAL_STATUS_FAILURE)
7000 {
7001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007002 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 }
7004
Jeff Johnson4416a782013-03-25 14:17:50 -07007005 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7007 eANI_BOOLEAN_FALSE) )
7008 {
7009 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007010 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 }
7012
7013 // Reset WNI_CFG_PROBE_RSP Flags
7014 wlan_hdd_reset_prob_rspies(pAdapter);
7015
7016 pAdapter->sessionCtx.ap.beacon = NULL;
7017 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007018#ifdef WLAN_FEATURE_P2P_DEBUG
7019 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7020 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7021 {
7022 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7023 "GO got removed");
7024 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7025 }
7026#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 }
7028 EXIT();
7029 return status;
7030}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007031
mukul sharma1cfb0682014-12-15 18:58:53 +05307032#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7033static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7034 struct net_device *dev)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044#else
7045static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7046 struct net_device *dev)
7047{
7048 int ret;
7049
7050 vos_ssr_protect(__func__);
7051 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7052 vos_ssr_unprotect(__func__);
7053
7054 return ret;
7055}
7056#endif
7057
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007058#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7059
mukul sharma1cfb0682014-12-15 18:58:53 +05307060static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307061 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007062 struct cfg80211_ap_settings *params)
7063{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307064 hdd_adapter_t *pAdapter;
7065 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307066 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007067
7068 ENTER();
7069
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307070 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307073 "%s: Device is Null", __func__);
7074 return -ENODEV;
7075 }
7076
7077 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7078 if (NULL == pAdapter)
7079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307081 "%s: HDD adapter is Null", __func__);
7082 return -ENODEV;
7083 }
7084
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7086 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7087 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307088 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7089 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307091 "%s: HDD adapter magic is invalid", __func__);
7092 return -ENODEV;
7093 }
7094
7095 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307096 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307097
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307098 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7101 "%s: HDD context is not valid", __func__);
7102 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307103 }
7104
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307105 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7106 __func__, hdd_device_modetoString(pAdapter->device_mode),
7107 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307108
7109 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007110 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007111 )
7112 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307113 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007114
7115 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307116
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007117 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307118 {
7119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7120 FL("already beacon info added to session(%d)"),
7121 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007122 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307123 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007124
7125 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7126
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307127 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007128 {
7129 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307130 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007131 return -EINVAL;
7132 }
7133 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007135 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7136#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7137 params->channel, params->channel_type);
7138#else
7139 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7140#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007141#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007142 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7143 params->ssid_len, params->hidden_ssid);
7144 }
7145
7146 EXIT();
7147 return status;
7148}
7149
mukul sharma1cfb0682014-12-15 18:58:53 +05307150static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7151 struct net_device *dev,
7152 struct cfg80211_ap_settings *params)
7153{
7154 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007155
mukul sharma1cfb0682014-12-15 18:58:53 +05307156 vos_ssr_protect(__func__);
7157 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7158 vos_ssr_unprotect(__func__);
7159
7160 return ret;
7161}
7162
7163static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007164 struct net_device *dev,
7165 struct cfg80211_beacon_data *params)
7166{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307167 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307168 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307169 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007170
7171 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307172
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307173 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7174 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7175 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007176 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007177 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307178
7179 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7180 status = wlan_hdd_validate_context(pHddCtx);
7181
7182 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007183 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7185 "%s: HDD context is not valid", __func__);
7186 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007187 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007188
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007190 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307191 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007192 {
7193 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307194
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007195 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307196
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007197 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307198 {
7199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7200 FL("session(%d) beacon data points to NULL"),
7201 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007202 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307203 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007204
7205 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7206
7207 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307208 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007209 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007210 return -EINVAL;
7211 }
7212
7213 pAdapter->sessionCtx.ap.beacon = new;
7214
7215 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7216 }
7217
7218 EXIT();
7219 return status;
7220}
7221
mukul sharma1cfb0682014-12-15 18:58:53 +05307222static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7223 struct net_device *dev,
7224 struct cfg80211_beacon_data *params)
7225{
7226 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007227
mukul sharma1cfb0682014-12-15 18:58:53 +05307228 vos_ssr_protect(__func__);
7229 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7230 vos_ssr_unprotect(__func__);
7231
7232 return ret;
7233}
7234
7235#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007236
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307237static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 struct net_device *dev,
7239 struct bss_parameters *params)
7240{
7241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7242
7243 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7246 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7247 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7249 __func__, hdd_device_modetoString(pAdapter->device_mode),
7250 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007251
7252 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307254 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 {
7256 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7257 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307258 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 {
7260 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 }
7263
7264 EXIT();
7265 return 0;
7266}
7267
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307268static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7269 struct net_device *dev,
7270 struct bss_parameters *params)
7271{
7272 int ret;
7273
7274 vos_ssr_protect(__func__);
7275 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7276 vos_ssr_unprotect(__func__);
7277
7278 return ret;
7279}
Kiet Lam10841362013-11-01 11:36:50 +05307280/* FUNCTION: wlan_hdd_change_country_code_cd
7281* to wait for contry code completion
7282*/
7283void* wlan_hdd_change_country_code_cb(void *pAdapter)
7284{
7285 hdd_adapter_t *call_back_pAdapter = pAdapter;
7286 complete(&call_back_pAdapter->change_country_code);
7287 return NULL;
7288}
7289
Jeff Johnson295189b2012-06-20 16:38:30 -07007290/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307291 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7293 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307294int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 struct net_device *ndev,
7296 enum nl80211_iftype type,
7297 u32 *flags,
7298 struct vif_params *params
7299 )
7300{
7301 struct wireless_dev *wdev;
7302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007303 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007304 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 tCsrRoamProfile *pRoamProfile = NULL;
7306 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307307 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 eMib_dot11DesiredBssType connectedBssType;
7309 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307310 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007311
7312 ENTER();
7313
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307314 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007315 {
7316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7317 "%s: Adapter context is null", __func__);
7318 return VOS_STATUS_E_FAILURE;
7319 }
7320
7321 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7322 if (!pHddCtx)
7323 {
7324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7325 "%s: HDD context is null", __func__);
7326 return VOS_STATUS_E_FAILURE;
7327 }
7328
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7330 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7331 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307332 status = wlan_hdd_validate_context(pHddCtx);
7333
7334 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7337 "%s: HDD context is not valid", __func__);
7338 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 }
7340
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7342 __func__, hdd_device_modetoString(pAdapter->device_mode),
7343 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344
Agarwal Ashish51325b52014-06-16 16:50:49 +05307345 if (vos_max_concurrent_connections_reached()) {
7346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7347 return -EINVAL;
7348 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307349 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 wdev = ndev->ieee80211_ptr;
7351
7352#ifdef WLAN_BTAMP_FEATURE
7353 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7354 (NL80211_IFTYPE_ADHOC == type)||
7355 (NL80211_IFTYPE_AP == type)||
7356 (NL80211_IFTYPE_P2P_GO == type))
7357 {
7358 pHddCtx->isAmpAllowed = VOS_FALSE;
7359 // stop AMP traffic
7360 status = WLANBAP_StopAmp();
7361 if(VOS_STATUS_SUCCESS != status )
7362 {
7363 pHddCtx->isAmpAllowed = VOS_TRUE;
7364 hddLog(VOS_TRACE_LEVEL_FATAL,
7365 "%s: Failed to stop AMP", __func__);
7366 return -EINVAL;
7367 }
7368 }
7369#endif //WLAN_BTAMP_FEATURE
7370 /* Reset the current device mode bit mask*/
7371 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7372
7373 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007375 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 )
7377 {
7378 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007379 if (!pWextState)
7380 {
7381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7382 "%s: pWextState is null", __func__);
7383 return VOS_STATUS_E_FAILURE;
7384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 pRoamProfile = &pWextState->roamProfile;
7386 LastBSSType = pRoamProfile->BSSType;
7387
7388 switch (type)
7389 {
7390 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 hddLog(VOS_TRACE_LEVEL_INFO,
7393 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7394 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007395#ifdef WLAN_FEATURE_11AC
7396 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7397 {
7398 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7399 }
7400#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307401 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007402 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007404 //Check for sub-string p2p to confirm its a p2p interface
7405 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307406 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007407 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7408 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7409 }
7410 else
7411 {
7412 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007414 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307415#ifdef FEATURE_WLAN_TDLS
7416 /* The open adapter for the p2p shall skip initializations in
7417 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
7418 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
7419 * tdls_init when the change_iface sets the device mode to
7420 * WLAN_HDD_P2P_CLIENT.
7421 */
7422
7423 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
7424 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05307425 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307426 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307427 hddLog(VOS_TRACE_LEVEL_ERROR,
7428 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05307429 return -EINVAL;
7430 }
7431 }
7432#endif
7433
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 break;
7435 case NL80211_IFTYPE_ADHOC:
7436 hddLog(VOS_TRACE_LEVEL_INFO,
7437 "%s: setting interface Type to ADHOC", __func__);
7438 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7439 pRoamProfile->phyMode =
7440 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007441 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 wdev->iftype = type;
7443 break;
7444
7445 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 {
7448 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7449 "%s: setting interface Type to %s", __func__,
7450 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7451
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007452 //Cancel any remain on channel for GO mode
7453 if (NL80211_IFTYPE_P2P_GO == type)
7454 {
7455 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7456 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007457 if (NL80211_IFTYPE_AP == type)
7458 {
7459 /* As Loading WLAN Driver one interface being created for p2p device
7460 * address. This will take one HW STA and the max number of clients
7461 * that can connect to softAP will be reduced by one. so while changing
7462 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7463 * interface as it is not required in SoftAP mode.
7464 */
7465
7466 // Get P2P Adapter
7467 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7468
7469 if (pP2pAdapter)
7470 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307471 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007472 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7473 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7474 }
7475 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307476 //Disable IMPS & BMPS for SAP/GO
7477 if(VOS_STATUS_E_FAILURE ==
7478 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7479 {
7480 //Fail to Exit BMPS
7481 VOS_ASSERT(0);
7482 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307483
7484 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7485
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307486#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007487
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307488 /* A Mutex Lock is introduced while changing the mode to
7489 * protect the concurrent access for the Adapters by TDLS
7490 * module.
7491 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307492 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307493#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 //De-init the adapter.
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 hdd_deinit_adapter( pHddCtx, pAdapter );
7496 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7498 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307499#ifdef FEATURE_WLAN_TDLS
7500 mutex_unlock(&pHddCtx->tdls_lock);
7501#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007502 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7503 (pConfig->apRandomBssidEnabled))
7504 {
7505 /* To meet Android requirements create a randomized
7506 MAC address of the form 02:1A:11:Fx:xx:xx */
7507 get_random_bytes(&ndev->dev_addr[3], 3);
7508 ndev->dev_addr[0] = 0x02;
7509 ndev->dev_addr[1] = 0x1A;
7510 ndev->dev_addr[2] = 0x11;
7511 ndev->dev_addr[3] |= 0xF0;
7512 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7513 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007514 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7515 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007516 }
7517
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 hdd_set_ap_ops( pAdapter->dev );
7519
Kiet Lam10841362013-11-01 11:36:50 +05307520 /* This is for only SAP mode where users can
7521 * control country through ini.
7522 * P2P GO follows station country code
7523 * acquired during the STA scanning. */
7524 if((NL80211_IFTYPE_AP == type) &&
7525 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7526 {
7527 int status = 0;
7528 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7529 "%s: setting country code from INI ", __func__);
7530 init_completion(&pAdapter->change_country_code);
7531 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7532 (void *)(tSmeChangeCountryCallback)
7533 wlan_hdd_change_country_code_cb,
7534 pConfig->apCntryCode, pAdapter,
7535 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307536 eSIR_FALSE,
7537 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307538 if (eHAL_STATUS_SUCCESS == status)
7539 {
7540 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307541 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307542 &pAdapter->change_country_code,
7543 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307544 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307545 {
7546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307547 FL("SME Timed out while setting country code %ld"),
7548 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007549
7550 if (pHddCtx->isLogpInProgress)
7551 {
7552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7553 "%s: LOGP in Progress. Ignore!!!", __func__);
7554 return -EAGAIN;
7555 }
Kiet Lam10841362013-11-01 11:36:50 +05307556 }
7557 }
7558 else
7559 {
7560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007561 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307562 return -EINVAL;
7563 }
7564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007565 status = hdd_init_ap_mode(pAdapter);
7566 if(status != VOS_STATUS_SUCCESS)
7567 {
7568 hddLog(VOS_TRACE_LEVEL_FATAL,
7569 "%s: Error initializing the ap mode", __func__);
7570 return -EINVAL;
7571 }
7572 hdd_set_conparam(1);
7573
Jeff Johnson295189b2012-06-20 16:38:30 -07007574 /*interface type changed update in wiphy structure*/
7575 if(wdev)
7576 {
7577 wdev->iftype = type;
7578 pHddCtx->change_iface = type;
7579 }
7580 else
7581 {
7582 hddLog(VOS_TRACE_LEVEL_ERROR,
7583 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7584 return -EINVAL;
7585 }
7586 goto done;
7587 }
7588
7589 default:
7590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7591 __func__);
7592 return -EOPNOTSUPP;
7593 }
7594 }
7595 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 )
7598 {
7599 switch(type)
7600 {
7601 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307604
7605 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307606#ifdef FEATURE_WLAN_TDLS
7607
7608 /* A Mutex Lock is introduced while changing the mode to
7609 * protect the concurrent access for the Adapters by TDLS
7610 * module.
7611 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307612 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307613#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07007614 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007616 //Check for sub-string p2p to confirm its a p2p interface
7617 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007618 {
7619 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7620 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7621 }
7622 else
7623 {
7624 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007626 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 hdd_set_conparam(0);
7628 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7630 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307631#ifdef FEATURE_WLAN_TDLS
7632 mutex_unlock(&pHddCtx->tdls_lock);
7633#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307634 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 if( VOS_STATUS_SUCCESS != status )
7636 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007637 /* In case of JB, for P2P-GO, only change interface will be called,
7638 * This is the right place to enable back bmps_imps()
7639 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307640 if (pHddCtx->hdd_wlan_suspended)
7641 {
7642 hdd_set_pwrparams(pHddCtx);
7643 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007644 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 goto done;
7646 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007649 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7650 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 goto done;
7652 default:
7653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7654 __func__);
7655 return -EOPNOTSUPP;
7656
7657 }
7658
7659 }
7660 else
7661 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307662 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7663 __func__, hdd_device_modetoString(pAdapter->device_mode),
7664 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 return -EOPNOTSUPP;
7666 }
7667
7668
7669 if(pRoamProfile)
7670 {
7671 if ( LastBSSType != pRoamProfile->BSSType )
7672 {
7673 /*interface type changed update in wiphy structure*/
7674 wdev->iftype = type;
7675
7676 /*the BSS mode changed, We need to issue disconnect
7677 if connected or in IBSS disconnect state*/
7678 if ( hdd_connGetConnectedBssType(
7679 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7680 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7681 {
7682 /*need to issue a disconnect to CSR.*/
7683 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7684 if( eHAL_STATUS_SUCCESS ==
7685 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7686 pAdapter->sessionId,
7687 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7688 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307689 ret = wait_for_completion_interruptible_timeout(
7690 &pAdapter->disconnect_comp_var,
7691 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7692 if (ret <= 0)
7693 {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("wait on disconnect_comp_var failed %ld"), ret);
7696 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 }
7698 }
7699 }
7700 }
7701
7702done:
7703 /*set bitmask based on updated value*/
7704 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007705
7706 /* Only STA mode support TM now
7707 * all other mode, TM feature should be disabled */
7708 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7709 (~VOS_STA & pHddCtx->concurrency_mode) )
7710 {
7711 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7712 }
7713
Jeff Johnson295189b2012-06-20 16:38:30 -07007714#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307715 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307716 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 {
7718 //we are ok to do AMP
7719 pHddCtx->isAmpAllowed = VOS_TRUE;
7720 }
7721#endif //WLAN_BTAMP_FEATURE
7722 EXIT();
7723 return 0;
7724}
7725
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307726/*
7727 * FUNCTION: wlan_hdd_cfg80211_change_iface
7728 * wrapper function to protect the actual implementation from SSR.
7729 */
7730int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7731 struct net_device *ndev,
7732 enum nl80211_iftype type,
7733 u32 *flags,
7734 struct vif_params *params
7735 )
7736{
7737 int ret;
7738
7739 vos_ssr_protect(__func__);
7740 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7741 vos_ssr_unprotect(__func__);
7742
7743 return ret;
7744}
7745
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007746#ifdef FEATURE_WLAN_TDLS
7747static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7748 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7749{
7750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7751 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7752 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007753 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307754 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307755 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007756
7757 ENTER();
7758
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307759 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007760 {
7761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7762 "Invalid arguments");
7763 return -EINVAL;
7764 }
Hoonki Lee27511902013-03-14 18:19:06 -07007765
7766 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7767 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7768 {
7769 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7770 "%s: TDLS mode is disabled OR not enabled in FW."
7771 MAC_ADDRESS_STR " Request declined.",
7772 __func__, MAC_ADDR_ARRAY(mac));
7773 return -ENOTSUPP;
7774 }
7775
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007776 if (pHddCtx->isLogpInProgress)
7777 {
7778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7779 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307780 wlan_hdd_tdls_set_link_status(pAdapter,
7781 mac,
7782 eTDLS_LINK_IDLE,
7783 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007784 return -EBUSY;
7785 }
7786
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307787 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007788
7789 if ( NULL == pTdlsPeer ) {
7790 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7791 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7792 __func__, MAC_ADDR_ARRAY(mac), update);
7793 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007794 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007795
7796 /* in add station, we accept existing valid staId if there is */
7797 if ((0 == update) &&
7798 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7799 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007800 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007801 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007802 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007803 " link_status %d. staId %d. add station ignored.",
7804 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7805 return 0;
7806 }
7807 /* in change station, we accept only when staId is valid */
7808 if ((1 == update) &&
7809 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7810 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7811 {
7812 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7813 "%s: " MAC_ADDRESS_STR
7814 " link status %d. staId %d. change station %s.",
7815 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7816 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7817 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007818 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007819
7820 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307821 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007822 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7824 "%s: " MAC_ADDRESS_STR
7825 " TDLS setup is ongoing. Request declined.",
7826 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007827 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007828 }
7829
7830 /* first to check if we reached to maximum supported TDLS peer.
7831 TODO: for now, return -EPERM looks working fine,
7832 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307833 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7834 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007835 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7837 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307838 " TDLS Max peer already connected. Request declined."
7839 " Num of peers (%d), Max allowed (%d).",
7840 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7841 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007842 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007843 }
7844 else
7845 {
7846 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307847 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007848 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007849 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7851 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7852 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007853 return -EPERM;
7854 }
7855 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007856 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307857 wlan_hdd_tdls_set_link_status(pAdapter,
7858 mac,
7859 eTDLS_LINK_CONNECTING,
7860 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007861
Jeff Johnsond75fe012013-04-06 10:53:06 -07007862 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307863 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007864 {
7865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7866 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007867 if(StaParams->htcap_present)
7868 {
7869 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7870 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7872 "ht_capa->extended_capabilities: %0x",
7873 StaParams->HTCap.extendedHtCapInfo);
7874 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007875 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7876 "params->capability: %0x",StaParams->capability);
7877 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007878 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007879 if(StaParams->vhtcap_present)
7880 {
7881 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7882 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7883 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7884 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7885 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007886 {
7887 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007889 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7890 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7891 "[%d]: %x ", i, StaParams->supported_rates[i]);
7892 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007893 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307894 else if ((1 == update) && (NULL == StaParams))
7895 {
7896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7897 "%s : update is true, but staParams is NULL. Error!", __func__);
7898 return -EPERM;
7899 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007900
7901 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7902
7903 if (!update)
7904 {
7905 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7906 pAdapter->sessionId, mac);
7907 }
7908 else
7909 {
7910 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7911 pAdapter->sessionId, mac, StaParams);
7912 }
7913
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307914 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007915 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7916
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307917 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007918 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307920 "%s: timeout waiting for tdls add station indication %ld",
7921 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007922 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007923 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307924
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007925 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7926 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007928 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007929 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007930 }
7931
7932 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007933
7934error:
Atul Mittal115287b2014-07-08 13:26:33 +05307935 wlan_hdd_tdls_set_link_status(pAdapter,
7936 mac,
7937 eTDLS_LINK_IDLE,
7938 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007939 return -EPERM;
7940
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007941}
7942#endif
7943
Jeff Johnson295189b2012-06-20 16:38:30 -07007944static int wlan_hdd_change_station(struct wiphy *wiphy,
7945 struct net_device *dev,
7946 u8 *mac,
7947 struct station_parameters *params)
7948{
7949 VOS_STATUS status = VOS_STATUS_SUCCESS;
7950 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05307951 hdd_context_t *pHddCtx;
7952 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007954#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007955 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007956 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307957 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007958#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007959 ENTER();
7960
Gopichand Nakkala29149562013-05-10 21:43:41 +05307961 if ((NULL == pAdapter))
7962 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307964 "invalid adapter ");
7965 return -EINVAL;
7966 }
7967
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7969 TRACE_CODE_HDD_CHANGE_STATION,
7970 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05307971 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7972 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7973
7974 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
7975 {
7976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7977 "invalid HDD state or HDD station context");
7978 return -EINVAL;
7979 }
7980
7981 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007982 {
7983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7984 "%s:LOGP in Progress. Ignore!!!", __func__);
7985 return -EAGAIN;
7986 }
7987
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
7989
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007990 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
7991 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007993 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307995 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 WLANTL_STA_AUTHENTICATED);
7997
Gopichand Nakkala29149562013-05-10 21:43:41 +05307998 if (status != VOS_STATUS_SUCCESS)
7999 {
8000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8001 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8002 return -EINVAL;
8003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 }
8005 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008006 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8007 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308008#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008009 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8010 StaParams.capability = params->capability;
8011 StaParams.uapsd_queues = params->uapsd_queues;
8012 StaParams.max_sp = params->max_sp;
8013
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308014 /* Convert (first channel , number of channels) tuple to
8015 * the total list of channels. This goes with the assumption
8016 * that if the first channel is < 14, then the next channels
8017 * are an incremental of 1 else an incremental of 4 till the number
8018 * of channels.
8019 */
8020 if (0 != params->supported_channels_len) {
8021 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8022 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8023 {
8024 int wifi_chan_index;
8025 StaParams.supported_channels[j] = params->supported_channels[i];
8026 wifi_chan_index =
8027 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8028 no_of_channels = params->supported_channels[i+1];
8029 for(k=1; k <= no_of_channels; k++)
8030 {
8031 StaParams.supported_channels[j+1] =
8032 StaParams.supported_channels[j] + wifi_chan_index;
8033 j+=1;
8034 }
8035 }
8036 StaParams.supported_channels_len = j;
8037 }
8038 vos_mem_copy(StaParams.supported_oper_classes,
8039 params->supported_oper_classes,
8040 params->supported_oper_classes_len);
8041 StaParams.supported_oper_classes_len =
8042 params->supported_oper_classes_len;
8043
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008044 if (0 != params->ext_capab_len)
8045 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8046 sizeof(StaParams.extn_capability));
8047
8048 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008049 {
8050 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008051 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008052 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008053
8054 StaParams.supported_rates_len = params->supported_rates_len;
8055
8056 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8057 * The supported_rates array , for all the structures propogating till Add Sta
8058 * to the firmware has to be modified , if the supplicant (ieee80211) is
8059 * modified to send more rates.
8060 */
8061
8062 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8063 */
8064 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8065 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8066
8067 if (0 != StaParams.supported_rates_len) {
8068 int i = 0;
8069 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8070 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008072 "Supported Rates with Length %d", StaParams.supported_rates_len);
8073 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008075 "[%d]: %0x", i, StaParams.supported_rates[i]);
8076 }
8077
8078 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008079 {
8080 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008081 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008082 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008083
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008084 if (0 != params->ext_capab_len ) {
8085 /*Define A Macro : TODO Sunil*/
8086 if ((1<<4) & StaParams.extn_capability[3]) {
8087 isBufSta = 1;
8088 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308089 /* TDLS Channel Switching Support */
8090 if ((1<<6) & StaParams.extn_capability[3]) {
8091 isOffChannelSupported = 1;
8092 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008093 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308094 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8095 &StaParams, isBufSta,
8096 isOffChannelSupported);
8097
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308098 if (VOS_STATUS_SUCCESS != status) {
8099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8100 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8101 return -EINVAL;
8102 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008103 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8104
8105 if (VOS_STATUS_SUCCESS != status) {
8106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8107 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8108 return -EINVAL;
8109 }
8110 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008111#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308112 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008113 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 return status;
8115}
8116
8117/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308118 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 * This function is used to initialize the key information
8120 */
8121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308122static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 struct net_device *ndev,
8124 u8 key_index, bool pairwise,
8125 const u8 *mac_addr,
8126 struct key_params *params
8127 )
8128#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308129static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 struct net_device *ndev,
8131 u8 key_index, const u8 *mac_addr,
8132 struct key_params *params
8133 )
8134#endif
8135{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 tCsrRoamSetKey setKey;
8138 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308139 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008140 v_U32_t roamId= 0xFF;
8141 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 hdd_hostapd_state_t *pHostapdState;
8143 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008144 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308145 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008146
8147 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308148
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308149 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8150 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8151 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8153 status = wlan_hdd_validate_context(pHddCtx);
8154
8155 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8158 "%s: HDD context is not valid", __func__);
8159 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008160 }
8161
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8163 __func__, hdd_device_modetoString(pAdapter->device_mode),
8164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008165
8166 if (CSR_MAX_NUM_KEY <= key_index)
8167 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 key_index);
8170
8171 return -EINVAL;
8172 }
8173
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008174 if (CSR_MAX_KEY_LEN < params->key_len)
8175 {
8176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8177 params->key_len);
8178
8179 return -EINVAL;
8180 }
8181
8182 hddLog(VOS_TRACE_LEVEL_INFO,
8183 "%s: called with key index = %d & key length %d",
8184 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008185
8186 /*extract key idx, key len and key*/
8187 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8188 setKey.keyId = key_index;
8189 setKey.keyLength = params->key_len;
8190 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8191
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008192 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 {
8194 case WLAN_CIPHER_SUITE_WEP40:
8195 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8196 break;
8197
8198 case WLAN_CIPHER_SUITE_WEP104:
8199 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8200 break;
8201
8202 case WLAN_CIPHER_SUITE_TKIP:
8203 {
8204 u8 *pKey = &setKey.Key[0];
8205 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8206
8207 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8208
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008209 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008210
8211 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008212 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 |--------------|----------|----------|
8214 <---16bytes---><--8bytes--><--8bytes-->
8215
8216 */
8217 /*Sme expects the 32 bytes key to be in the below order
8218
8219 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008220 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 |--------------|----------|----------|
8222 <---16bytes---><--8bytes--><--8bytes-->
8223 */
8224 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008225 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008226
8227 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008228 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
8230 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008231 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008232
8233
8234 break;
8235 }
8236
8237 case WLAN_CIPHER_SUITE_CCMP:
8238 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8239 break;
8240
8241#ifdef FEATURE_WLAN_WAPI
8242 case WLAN_CIPHER_SUITE_SMS4:
8243 {
8244 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8245 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8246 params->key, params->key_len);
8247 return 0;
8248 }
8249#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008250
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008251#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 case WLAN_CIPHER_SUITE_KRK:
8253 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8254 break;
8255#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008256
8257#ifdef WLAN_FEATURE_11W
8258 case WLAN_CIPHER_SUITE_AES_CMAC:
8259 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008260 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008261#endif
8262
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 __func__, params->cipher);
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308266 status = -EOPNOTSUPP;
8267 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
8269
8270 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8271 __func__, setKey.encType);
8272
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008273 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8275 (!pairwise)
8276#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008277 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008278#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008279 )
8280 {
8281 /* set group key*/
8282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8283 "%s- %d: setting Broadcast key",
8284 __func__, __LINE__);
8285 setKey.keyDirection = eSIR_RX_ONLY;
8286 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8287 }
8288 else
8289 {
8290 /* set pairwise key*/
8291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8292 "%s- %d: setting pairwise key",
8293 __func__, __LINE__);
8294 setKey.keyDirection = eSIR_TX_RX;
8295 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8296 }
8297 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8298 {
8299 setKey.keyDirection = eSIR_TX_RX;
8300 /*Set the group key*/
8301 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8302 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008303
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008304 if ( 0 != status )
8305 {
8306 hddLog(VOS_TRACE_LEVEL_ERROR,
8307 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308308 status = -EINVAL;
8309 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008310 }
8311 /*Save the keys here and call sme_RoamSetKey for setting
8312 the PTK after peer joins the IBSS network*/
8313 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8314 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308315 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008316 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308317 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8318 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8319 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008320 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008321 if( pHostapdState->bssState == BSS_START )
8322 {
c_hpothu7c55da62014-01-23 18:34:02 +05308323 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8324 vos_status = wlan_hdd_check_ula_done(pAdapter);
8325
8326 if ( vos_status != VOS_STATUS_SUCCESS )
8327 {
8328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8329 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8330 __LINE__, vos_status );
8331
8332 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8333
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308334 status = -EINVAL;
8335 goto end;
c_hpothu7c55da62014-01-23 18:34:02 +05308336 }
8337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8339
8340 if ( status != eHAL_STATUS_SUCCESS )
8341 {
8342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8343 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8344 __LINE__, status );
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308345 status = -EINVAL;
8346 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008347 }
8348 }
8349
8350 /* Saving WEP keys */
8351 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8352 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8353 {
8354 //Save the wep key in ap context. Issue setkey after the BSS is started.
8355 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8356 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8357 }
8358 else
8359 {
8360 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008361 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8363 }
8364 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008365 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8366 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 {
8368 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8369 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8370
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8372 if (!pairwise)
8373#else
8374 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8375#endif
8376 {
8377 /* set group key*/
8378 if (pHddStaCtx->roam_info.deferKeyComplete)
8379 {
8380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8381 "%s- %d: Perform Set key Complete",
8382 __func__, __LINE__);
8383 hdd_PerformRoamSetKeyComplete(pAdapter);
8384 }
8385 }
8386
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8388
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008389 pWextState->roamProfile.Keys.defaultIndex = key_index;
8390
8391
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008392 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 params->key, params->key_len);
8394
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308395
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8397
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308398 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008399 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308400 __func__, setKey.peerMac[0], setKey.peerMac[1],
8401 setKey.peerMac[2], setKey.peerMac[3],
8402 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 setKey.keyDirection);
8404
8405 vos_status = wlan_hdd_check_ula_done(pAdapter);
8406
8407 if ( vos_status != VOS_STATUS_SUCCESS )
8408 {
8409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8410 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8411 __LINE__, vos_status );
8412
8413 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8414
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308415 status = -EINVAL;
8416 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
8418 }
8419
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008420#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308421 /* The supplicant may attempt to set the PTK once pre-authentication
8422 is done. Save the key in the UMAC and include it in the ADD BSS
8423 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008424 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308425 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008426 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308427 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8428 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308429 status = 0;
8430 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308431 }
8432 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8433 {
8434 hddLog(VOS_TRACE_LEVEL_ERROR,
8435 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308436 status = -EINVAL;
8437 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008438 }
8439#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008440
8441 /* issue set key request to SME*/
8442 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8443 pAdapter->sessionId, &setKey, &roamId );
8444
8445 if ( 0 != status )
8446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8449 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308450 status = -EINVAL;
8451 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 }
8453
8454
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455 /* in case of IBSS as there was no information available about WEP keys during
8456 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308458 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8459 !( ( IW_AUTH_KEY_MGMT_802_1X
8460 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8462 )
8463 &&
8464 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8465 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8466 )
8467 )
8468 {
8469 setKey.keyDirection = eSIR_RX_ONLY;
8470 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8471
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308474 __func__, setKey.peerMac[0], setKey.peerMac[1],
8475 setKey.peerMac[2], setKey.peerMac[3],
8476 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 setKey.keyDirection);
8478
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 pAdapter->sessionId, &setKey, &roamId );
8481
8482 if ( 0 != status )
8483 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308484 hddLog(VOS_TRACE_LEVEL_ERROR,
8485 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 __func__, status);
8487 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308488 status = -EINVAL;
8489 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008490 }
8491 }
8492 }
8493
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +05308494end:
8495 /* Need to clear any trace of key value in the memory.
8496 * Thus zero out the memory even though it is local
8497 * variable.
8498 */
8499 vos_mem_zero(&setKey, sizeof(setKey));
8500
8501 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008502}
8503
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8505static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8506 struct net_device *ndev,
8507 u8 key_index, bool pairwise,
8508 const u8 *mac_addr,
8509 struct key_params *params
8510 )
8511#else
8512static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8513 struct net_device *ndev,
8514 u8 key_index, const u8 *mac_addr,
8515 struct key_params *params
8516 )
8517#endif
8518{
8519 int ret;
8520 vos_ssr_protect(__func__);
8521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8522 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8523 mac_addr, params);
8524#else
8525 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8526 params);
8527#endif
8528 vos_ssr_unprotect(__func__);
8529
8530 return ret;
8531}
8532
Jeff Johnson295189b2012-06-20 16:38:30 -07008533/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308534 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 * This function is used to get the key information
8536 */
8537#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308538static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308539 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308541 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008542 const u8 *mac_addr, void *cookie,
8543 void (*callback)(void *cookie, struct key_params*)
8544 )
8545#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308546static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308547 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 struct net_device *ndev,
8549 u8 key_index, const u8 *mac_addr, void *cookie,
8550 void (*callback)(void *cookie, struct key_params*)
8551 )
8552#endif
8553{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308555 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8556 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 struct key_params params;
8558
8559 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308560
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308561 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8562 __func__, hdd_device_modetoString(pAdapter->device_mode),
8563 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 memset(&params, 0, sizeof(params));
8566
8567 if (CSR_MAX_NUM_KEY <= key_index)
8568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008572
8573 switch(pRoamProfile->EncryptionType.encryptionType[0])
8574 {
8575 case eCSR_ENCRYPT_TYPE_NONE:
8576 params.cipher = IW_AUTH_CIPHER_NONE;
8577 break;
8578
8579 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8580 case eCSR_ENCRYPT_TYPE_WEP40:
8581 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8582 break;
8583
8584 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8585 case eCSR_ENCRYPT_TYPE_WEP104:
8586 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8587 break;
8588
8589 case eCSR_ENCRYPT_TYPE_TKIP:
8590 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8591 break;
8592
8593 case eCSR_ENCRYPT_TYPE_AES:
8594 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8595 break;
8596
8597 default:
8598 params.cipher = IW_AUTH_CIPHER_NONE;
8599 break;
8600 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308601
c_hpothuaaf19692014-05-17 17:01:48 +05308602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8603 TRACE_CODE_HDD_CFG80211_GET_KEY,
8604 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308605
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8607 params.seq_len = 0;
8608 params.seq = NULL;
8609 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8610 callback(cookie, &params);
8611 return 0;
8612}
8613
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8615static int wlan_hdd_cfg80211_get_key(
8616 struct wiphy *wiphy,
8617 struct net_device *ndev,
8618 u8 key_index, bool pairwise,
8619 const u8 *mac_addr, void *cookie,
8620 void (*callback)(void *cookie, struct key_params*)
8621 )
8622#else
8623static int wlan_hdd_cfg80211_get_key(
8624 struct wiphy *wiphy,
8625 struct net_device *ndev,
8626 u8 key_index, const u8 *mac_addr, void *cookie,
8627 void (*callback)(void *cookie, struct key_params*)
8628 )
8629#endif
8630{
8631 int ret;
8632
8633 vos_ssr_protect(__func__);
8634#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8635 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8636 mac_addr, cookie, callback);
8637#else
8638 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8639 callback);
8640#endif
8641 vos_ssr_unprotect(__func__);
8642
8643 return ret;
8644}
8645
Jeff Johnson295189b2012-06-20 16:38:30 -07008646/*
8647 * FUNCTION: wlan_hdd_cfg80211_del_key
8648 * This function is used to delete the key information
8649 */
8650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308651static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308653 u8 key_index,
8654 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008655 const u8 *mac_addr
8656 )
8657#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308658static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 struct net_device *ndev,
8660 u8 key_index,
8661 const u8 *mac_addr
8662 )
8663#endif
8664{
8665 int status = 0;
8666
8667 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308668 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 //it is observed that this is invalidating peer
8670 //key index whenever re-key is done. This is affecting data link.
8671 //It should be ok to ignore del_key.
8672#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8674 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8676 tCsrRoamSetKey setKey;
8677 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308678
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 ENTER();
8680
8681 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8682 __func__,pAdapter->device_mode);
8683
8684 if (CSR_MAX_NUM_KEY <= key_index)
8685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 key_index);
8688
8689 return -EINVAL;
8690 }
8691
8692 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8693 setKey.keyId = key_index;
8694
8695 if (mac_addr)
8696 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8697 else
8698 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8699
8700 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8701
8702 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308704 )
8705 {
8706
8707 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8709 if( pHostapdState->bssState == BSS_START)
8710 {
8711 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308712
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 if ( status != eHAL_STATUS_SUCCESS )
8714 {
8715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8716 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8717 __LINE__, status );
8718 }
8719 }
8720 }
8721 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308722 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008723 )
8724 {
8725 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8726
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308727 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8728
8729 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008730 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308731 __func__, setKey.peerMac[0], setKey.peerMac[1],
8732 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308734 if(pAdapter->sessionCtx.station.conn_info.connState ==
8735 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308737 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308739
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 if ( 0 != status )
8741 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308742 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 "%s: sme_RoamSetKey failure, returned %d",
8744 __func__, status);
8745 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8746 return -EINVAL;
8747 }
8748 }
8749 }
8750#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008751 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 return status;
8753}
8754
8755/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308756 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 * This function is used to set the default tx key index
8758 */
8759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308760static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 struct net_device *ndev,
8762 u8 key_index,
8763 bool unicast, bool multicast)
8764#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308765static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 struct net_device *ndev,
8767 u8 key_index)
8768#endif
8769{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308771 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308772 hdd_wext_state_t *pWextState;
8773 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308774 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008775
8776 ENTER();
8777
Gopichand Nakkala29149562013-05-10 21:43:41 +05308778 if ((NULL == pAdapter))
8779 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308781 "invalid adapter");
8782 return -EINVAL;
8783 }
8784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8786 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8787 pAdapter->sessionId, key_index));
8788
Gopichand Nakkala29149562013-05-10 21:43:41 +05308789 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8791
8792 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8793 {
8794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8795 "invalid Wext state or HDD context");
8796 return -EINVAL;
8797 }
8798
Arif Hussain6d2a3322013-11-17 19:50:10 -08008799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308801
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 if (CSR_MAX_NUM_KEY <= key_index)
8803 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 key_index);
8806
8807 return -EINVAL;
8808 }
8809
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308810 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8811 status = wlan_hdd_validate_context(pHddCtx);
8812
8813 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8816 "%s: HDD context is not valid", __func__);
8817 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008818 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308819
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308822 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308824 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008825 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308826 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008827 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308829 {
8830 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308832
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 tCsrRoamSetKey setKey;
8834 v_U32_t roamId= 0xFF;
8835 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308836
8837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308839
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 Keys->defaultIndex = (u8)key_index;
8841 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8842 setKey.keyId = key_index;
8843 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308844
8845 vos_mem_copy(&setKey.Key[0],
8846 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308848
Gopichand Nakkala29149562013-05-10 21:43:41 +05308849 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308850
8851 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 &pHddStaCtx->conn_info.bssId[0],
8853 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308854
Gopichand Nakkala29149562013-05-10 21:43:41 +05308855 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8856 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8857 eCSR_ENCRYPT_TYPE_WEP104)
8858 {
8859 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8860 even though ap is configured for WEP-40 encryption. In this canse the key length
8861 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8862 type(104) and switching encryption type to 40*/
8863 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8864 eCSR_ENCRYPT_TYPE_WEP40;
8865 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
8866 eCSR_ENCRYPT_TYPE_WEP40;
8867 }
8868
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308869 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308871
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 if ( 0 != status )
8877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308878 hddLog(VOS_TRACE_LEVEL_ERROR,
8879 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 status);
8881 return -EINVAL;
8882 }
8883 }
8884 }
8885
8886 /* In SoftAp mode setting key direction for default mode */
8887 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
8888 {
8889 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
8890 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
8891 (eCSR_ENCRYPT_TYPE_AES !=
8892 pWextState->roamProfile.EncryptionType.encryptionType[0])
8893 )
8894 {
8895 /* Saving key direction for default key index to TX default */
8896 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8897 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
8898 }
8899 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308900
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 return status;
8902}
8903
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8905static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8906 struct net_device *ndev,
8907 u8 key_index,
8908 bool unicast, bool multicast)
8909#else
8910static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
8911 struct net_device *ndev,
8912 u8 key_index)
8913#endif
8914{
8915 int ret;
8916 vos_ssr_protect(__func__);
8917#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8918 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
8919 multicast);
8920#else
8921 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
8922#endif
8923 vos_ssr_unprotect(__func__);
8924
8925 return ret;
8926}
8927
Jeff Johnson295189b2012-06-20 16:38:30 -07008928/*
8929 * FUNCTION: wlan_hdd_cfg80211_inform_bss
8930 * This function is used to inform the BSS details to nl80211 interface.
8931 */
8932static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
8933 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
8934{
8935 struct net_device *dev = pAdapter->dev;
8936 struct wireless_dev *wdev = dev->ieee80211_ptr;
8937 struct wiphy *wiphy = wdev->wiphy;
8938 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
8939 int chan_no;
8940 int ie_length;
8941 const char *ie;
8942 unsigned int freq;
8943 struct ieee80211_channel *chan;
8944 int rssi = 0;
8945 struct cfg80211_bss *bss = NULL;
8946
8947 ENTER();
8948
8949 if( NULL == pBssDesc )
8950 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008951 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 return bss;
8953 }
8954
8955 chan_no = pBssDesc->channelId;
8956 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
8957 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
8958
8959 if( NULL == ie )
8960 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008961 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 return bss;
8963 }
8964
8965#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8966 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8967 {
8968 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8969 }
8970 else
8971 {
8972 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8973 }
8974#else
8975 freq = ieee80211_channel_to_frequency(chan_no);
8976#endif
8977
8978 chan = __ieee80211_get_channel(wiphy, freq);
8979
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05308980 if (!chan) {
8981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
8982 return NULL;
8983 }
8984
Abhishek Singhaee43942014-06-16 18:55:47 +05308985 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07008986
Abhishek Singhaee43942014-06-16 18:55:47 +05308987 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308988 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 pBssDesc->capabilityInfo,
8990 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05308991 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07008992}
8993
8994
8995
8996/*
8997 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
8998 * This function is used to inform the BSS details to nl80211 interface.
8999 */
9000struct cfg80211_bss*
9001wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9002 tSirBssDescription *bss_desc
9003 )
9004{
9005 /*
9006 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9007 already exists in bss data base of cfg80211 for that particular BSS ID.
9008 Using cfg80211_inform_bss_frame to update the bss entry instead of
9009 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9010 now there is no possibility to get the mgmt(probe response) frame from PE,
9011 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9012 cfg80211_inform_bss_frame.
9013 */
9014 struct net_device *dev = pAdapter->dev;
9015 struct wireless_dev *wdev = dev->ieee80211_ptr;
9016 struct wiphy *wiphy = wdev->wiphy;
9017 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009018#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9019 qcom_ie_age *qie_age = NULL;
9020 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9021#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009023#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 const char *ie =
9025 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9026 unsigned int freq;
9027 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309028 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009029 struct cfg80211_bss *bss_status = NULL;
9030 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9031 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009032 hdd_context_t *pHddCtx;
9033 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009034#ifdef WLAN_OPEN_SOURCE
9035 struct timespec ts;
9036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009037
Wilson Yangf80a0542013-10-07 13:02:37 -07009038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9039 status = wlan_hdd_validate_context(pHddCtx);
9040
9041 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309042 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009043 {
9044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9045 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9046 return NULL;
9047 }
9048
9049
9050 if (0 != status)
9051 {
9052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9053 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009054 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009055 }
9056
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309057 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009058 if (!mgmt)
9059 {
9060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9061 "%s: memory allocation failed ", __func__);
9062 return NULL;
9063 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009064
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009066
9067#ifdef WLAN_OPEN_SOURCE
9068 /* Android does not want the timestamp from the frame.
9069 Instead it wants a monotonic increasing value */
9070 get_monotonic_boottime(&ts);
9071 mgmt->u.probe_resp.timestamp =
9072 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9073#else
9074 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9076 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009077
9078#endif
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9081 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009082
9083#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9084 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9085 /* Assuming this is the last IE, copy at the end */
9086 ie_length -=sizeof(qcom_ie_age);
9087 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9088 qie_age->element_id = QCOM_VENDOR_IE_ID;
9089 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9090 qie_age->oui_1 = QCOM_OUI1;
9091 qie_age->oui_2 = QCOM_OUI2;
9092 qie_age->oui_3 = QCOM_OUI3;
9093 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9094 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9095#endif
9096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309098 if (bss_desc->fProbeRsp)
9099 {
9100 mgmt->frame_control |=
9101 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9102 }
9103 else
9104 {
9105 mgmt->frame_control |=
9106 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009108
9109#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309110 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9112 {
9113 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9114 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309115 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9117
9118 {
9119 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9120 }
9121 else
9122 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9124 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 kfree(mgmt);
9126 return NULL;
9127 }
9128#else
9129 freq = ieee80211_channel_to_frequency(chan_no);
9130#endif
9131 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009132 /*when the band is changed on the fly using the GUI, three things are done
9133 * 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)
9134 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9135 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9136 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9137 * and discards the channels correponding to previous band and calls back with zero bss results.
9138 * 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
9139 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9140 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9141 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9142 * So drop the bss and continue to next bss.
9143 */
9144 if(chan == NULL)
9145 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009147 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009148 return NULL;
9149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309151 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 * */
9153 if (( eConnectionState_Associated ==
9154 pAdapter->sessionCtx.station.conn_info.connState ) &&
9155 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9156 pAdapter->sessionCtx.station.conn_info.bssId,
9157 WNI_CFG_BSSID_LEN)))
9158 {
9159 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9160 rssi = (pAdapter->rssi * 100);
9161 }
9162 else
9163 {
9164 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9165 }
9166
Nirav Shah20ac06f2013-12-12 18:14:06 +05309167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9168 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9169 chan->center_freq, (int)(rssi/100));
9170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9172 frame_len, rssi, GFP_KERNEL);
9173 kfree(mgmt);
9174 return bss_status;
9175}
9176
9177/*
9178 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9179 * This function is used to update the BSS data base of CFG8011
9180 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309181struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 tCsrRoamInfo *pRoamInfo
9183 )
9184{
9185 tCsrRoamConnectedProfile roamProfile;
9186 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9187 struct cfg80211_bss *bss = NULL;
9188
9189 ENTER();
9190
9191 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9192 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9193
9194 if (NULL != roamProfile.pBssDesc)
9195 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309196 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9197 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009198
9199 if (NULL == bss)
9200 {
9201 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9202 __func__);
9203 }
9204
9205 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9206 }
9207 else
9208 {
9209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9210 __func__);
9211 }
9212 return bss;
9213}
9214
9215/*
9216 * FUNCTION: wlan_hdd_cfg80211_update_bss
9217 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309218static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9219 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309221{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309222 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 tCsrScanResultInfo *pScanResult;
9224 eHalStatus status = 0;
9225 tScanResultHandle pResult;
9226 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009227 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009228
9229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309230
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9232 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9233 NO_SESSION, pAdapter->sessionId));
9234
Wilson Yangf80a0542013-10-07 13:02:37 -07009235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9236
9237 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9240 "%s:LOGP in Progress. Ignore!!!",__func__);
9241 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 }
9243
Wilson Yangf80a0542013-10-07 13:02:37 -07009244
9245 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309246 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009247 {
9248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9249 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9250 return VOS_STATUS_E_PERM;
9251 }
9252
9253
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 /*
9255 * start getting scan results and populate cgf80211 BSS database
9256 */
9257 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9258
9259 /* no scan results */
9260 if (NULL == pResult)
9261 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9263 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 return status;
9265 }
9266
9267 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9268
9269 while (pScanResult)
9270 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309271 /*
9272 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9273 * entry already exists in bss data base of cfg80211 for that
9274 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9275 * bss entry instead of cfg80211_inform_bss, But this call expects
9276 * mgmt packet as input. As of now there is no possibility to get
9277 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 * ieee80211_mgmt(probe response) and passing to c
9279 * fg80211_inform_bss_frame.
9280 * */
9281
9282 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9283 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285
9286 if (NULL == bss_status)
9287 {
9288 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009289 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 }
9291 else
9292 {
Yue Maf49ba872013-08-19 12:04:25 -07009293 cfg80211_put_bss(
9294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9295 wiphy,
9296#endif
9297 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 }
9299
9300 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9301 }
9302
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009304
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309305 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009306}
9307
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009308void
9309hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9310{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009312 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009313} /****** end hddPrintMacAddr() ******/
9314
9315void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009316hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009317{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309318 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009319 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009320 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9321 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9322 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009323} /****** end hddPrintPmkId() ******/
9324
9325//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9326//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9327
9328//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9329//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9330
9331#define dump_bssid(bssid) \
9332 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009333 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9334 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009335 }
9336
9337#define dump_pmkid(pMac, pmkid) \
9338 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009339 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9340 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009341 }
9342
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009343#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009344/*
9345 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9346 * This function is used to notify the supplicant of a new PMKSA candidate.
9347 */
9348int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309349 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009350 int index, bool preauth )
9351{
Jeff Johnsone7245742012-09-05 17:12:55 -07009352#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009353 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009354 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009355
9356 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009357 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009358
9359 if( NULL == pRoamInfo )
9360 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009361 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009362 return -EINVAL;
9363 }
9364
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009365 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9366 {
9367 dump_bssid(pRoamInfo->bssid);
9368 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009369 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009370 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009371#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009373}
9374#endif //FEATURE_WLAN_LFR
9375
Yue Maef608272013-04-08 23:09:17 -07009376#ifdef FEATURE_WLAN_LFR_METRICS
9377/*
9378 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9379 * 802.11r/LFR metrics reporting function to report preauth initiation
9380 *
9381 */
9382#define MAX_LFR_METRICS_EVENT_LENGTH 100
9383VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9384 tCsrRoamInfo *pRoamInfo)
9385{
9386 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9387 union iwreq_data wrqu;
9388
9389 ENTER();
9390
9391 if (NULL == pAdapter)
9392 {
9393 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9394 return VOS_STATUS_E_FAILURE;
9395 }
9396
9397 /* create the event */
9398 memset(&wrqu, 0, sizeof(wrqu));
9399 memset(metrics_notification, 0, sizeof(metrics_notification));
9400
9401 wrqu.data.pointer = metrics_notification;
9402 wrqu.data.length = scnprintf(metrics_notification,
9403 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9404 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9405
9406 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9407
9408 EXIT();
9409
9410 return VOS_STATUS_SUCCESS;
9411}
9412
9413/*
9414 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9415 * 802.11r/LFR metrics reporting function to report preauth completion
9416 * or failure
9417 */
9418VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9419 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9420{
9421 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9422 union iwreq_data wrqu;
9423
9424 ENTER();
9425
9426 if (NULL == pAdapter)
9427 {
9428 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9429 return VOS_STATUS_E_FAILURE;
9430 }
9431
9432 /* create the event */
9433 memset(&wrqu, 0, sizeof(wrqu));
9434 memset(metrics_notification, 0, sizeof(metrics_notification));
9435
9436 scnprintf(metrics_notification, sizeof(metrics_notification),
9437 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9438 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9439
9440 if (1 == preauth_status)
9441 strncat(metrics_notification, " TRUE", 5);
9442 else
9443 strncat(metrics_notification, " FALSE", 6);
9444
9445 wrqu.data.pointer = metrics_notification;
9446 wrqu.data.length = strlen(metrics_notification);
9447
9448 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9449
9450 EXIT();
9451
9452 return VOS_STATUS_SUCCESS;
9453}
9454
9455/*
9456 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9457 * 802.11r/LFR metrics reporting function to report handover initiation
9458 *
9459 */
9460VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9461 tCsrRoamInfo *pRoamInfo)
9462{
9463 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9464 union iwreq_data wrqu;
9465
9466 ENTER();
9467
9468 if (NULL == pAdapter)
9469 {
9470 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9471 return VOS_STATUS_E_FAILURE;
9472 }
9473
9474 /* create the event */
9475 memset(&wrqu, 0, sizeof(wrqu));
9476 memset(metrics_notification, 0, sizeof(metrics_notification));
9477
9478 wrqu.data.pointer = metrics_notification;
9479 wrqu.data.length = scnprintf(metrics_notification,
9480 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9481 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9482
9483 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9484
9485 EXIT();
9486
9487 return VOS_STATUS_SUCCESS;
9488}
9489#endif
9490
Jeff Johnson295189b2012-06-20 16:38:30 -07009491/*
9492 * FUNCTION: hdd_cfg80211_scan_done_callback
9493 * scanning callback function, called after finishing scan
9494 *
9495 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309496static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9498{
9499 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309500 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009502 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9503 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 struct cfg80211_scan_request *req = NULL;
9505 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309506 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309507 long waitRet = 0;
Agarwal Ashish0335a322014-11-24 19:19:46 +05309508 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
9510 ENTER();
9511
9512 hddLog(VOS_TRACE_LEVEL_INFO,
9513 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009514 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 __func__, halHandle, pContext, (int) scanId, (int) status);
9516
Kiet Lamac06e2c2013-10-23 16:25:07 +05309517 pScanInfo->mScanPendingCounter = 0;
9518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309520 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 &pScanInfo->scan_req_completion_event,
9522 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309523 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009524 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309525 hddLog(VOS_TRACE_LEVEL_ERROR,
9526 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009527 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009528 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 }
9530
Yue Maef608272013-04-08 23:09:17 -07009531 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 {
9533 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009534 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 }
9536
9537 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 {
9540 hddLog(VOS_TRACE_LEVEL_INFO,
9541 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009542 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 (int) scanId);
9544 }
9545
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 pAdapter);
9548
9549 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
9552
9553 /* If any client wait scan result through WEXT
9554 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009555 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 {
9557 /* The other scan request waiting for current scan finish
9558 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009559 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009561 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 }
9563 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009564 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 {
9566 struct net_device *dev = pAdapter->dev;
9567 union iwreq_data wrqu;
9568 int we_event;
9569 char *msg;
9570
9571 memset(&wrqu, '\0', sizeof(wrqu));
9572 we_event = SIOCGIWSCAN;
9573 msg = NULL;
9574 wireless_send_event(dev, we_event, &wrqu, msg);
9575 }
9576 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009577 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
9579 /* Get the Scan Req */
9580 req = pAdapter->request;
9581
9582 if (!req)
9583 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009584 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009585 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009586 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 }
9588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009590 /* Scan is no longer pending */
9591 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009592
Agarwal Ashish0335a322014-11-24 19:19:46 +05309593 /* last_scan_timestamp is used to decide if new scan
9594 * is needed or not on station interface. If last station
9595 * scan time and new station scan time is less then
9596 * last_scan_timestamp ; driver will return cached scan.
9597 */
9598 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9599 {
9600 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9601
9602 if ( req->n_channels )
9603 {
9604 for (i = 0; i < req->n_channels ; i++ )
9605 {
9606 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9607 }
9608 /* store no of channel scanned */
9609 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9610 }
9611
9612 }
9613
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009614 /*
9615 * cfg80211_scan_done informing NL80211 about completion
9616 * of scanning
9617 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309618 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9619 {
9620 aborted = true;
9621 }
9622 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009623 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009624
Jeff Johnsone7245742012-09-05 17:12:55 -07009625allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009626 /* release the wake lock at the end of the scan*/
9627 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009628
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009629 /* Acquire wakelock to handle the case where APP's tries to suspend
9630 * immediatly after the driver gets connect request(i.e after scan)
9631 * from supplicant, this result in app's is suspending and not able
9632 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309633 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009634
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009635#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309636 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9637 {
9638 wlan_hdd_tdls_scan_done_callback(pAdapter);
9639 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009640#endif
9641
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 EXIT();
9643 return 0;
9644}
9645
9646/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309647 * FUNCTION: hdd_isConnectionInProgress
9648 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009649 *
9650 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309651v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx, v_BOOL_t isRoC )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009652{
9653 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9654 hdd_station_ctx_t *pHddStaCtx = NULL;
9655 hdd_adapter_t *pAdapter = NULL;
9656 VOS_STATUS status = 0;
9657 v_U8_t staId = 0;
9658 v_U8_t *staMac = NULL;
9659
c_hpothu9b781ba2013-12-30 20:57:45 +05309660 if (TRUE == pHddCtx->btCoexModeSet)
9661 {
9662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309663 FL("BTCoex Mode operation in progress"));
9664 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309665 }
9666
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9668
9669 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9670 {
9671 pAdapter = pAdapterNode->pAdapter;
9672
9673 if( pAdapter )
9674 {
9675 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309676 "%s: Adapter with device mode %s (%d) exists",
9677 __func__, hdd_device_modetoString(pAdapter->device_mode),
9678 pAdapter->device_mode);
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309679 if ((((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309680 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9681 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9682 (eConnectionState_Connecting ==
9683 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9684 {
9685 hddLog(VOS_TRACE_LEVEL_ERROR,
9686 "%s: %p(%d) Connection is in progress", __func__,
9687 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9688 return VOS_TRUE;
9689 }
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309690 if (((!isRoC) && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309691 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9692 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009693 {
9694 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9695 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309696 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009697 {
9698 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9699 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009700 "%s: client " MAC_ADDRESS_STR
9701 " is in the middle of WPS/EAPOL exchange.", __func__,
9702 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309703 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009704 }
9705 }
9706 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9707 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9708 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05309709 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9710 ptSapContext pSapCtx = NULL;
9711 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9712 if(pSapCtx == NULL){
9713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9714 FL("psapCtx is NULL"));
9715 return VOS_FALSE;
9716 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009717 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9718 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05309719 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9720 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009721 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +05309722 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009723
9724 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009725 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9726 "middle of WPS/EAPOL exchange.", __func__,
9727 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309728 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009729 }
9730 }
9731 }
9732 }
9733 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9734 pAdapterNode = pNext;
9735 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309736 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309737}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009738
9739/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309740 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 * this scan respond to scan trigger and update cfg80211 scan database
9742 * later, scan dump command can be used to recieve scan results
9743 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309744int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009745#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9746 struct net_device *dev,
9747#endif
9748 struct cfg80211_scan_request *request)
9749{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309750 hdd_adapter_t *pAdapter = NULL;
9751 hdd_context_t *pHddCtx = NULL;
9752 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309753 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 tCsrScanRequest scanRequest;
9755 tANI_U8 *channelList = NULL, i;
9756 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309757 int status;
9758 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 v_U8_t* pP2pIe = NULL;
Agarwal Ashish0335a322014-11-24 19:19:46 +05309760 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009761
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9763 struct net_device *dev = NULL;
9764 if (NULL == request)
9765 {
9766 hddLog(VOS_TRACE_LEVEL_ERROR,
9767 "%s: scan req param null", __func__);
9768 return -EINVAL;
9769 }
9770 dev = request->wdev->netdev;
9771#endif
9772
9773 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9774 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9775 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9776
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 ENTER();
9778
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309779
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9781 __func__, hdd_device_modetoString(pAdapter->device_mode),
9782 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309783
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309784 status = wlan_hdd_validate_context(pHddCtx);
9785
9786 if (0 != status)
9787 {
9788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9789 "%s: HDD context is not valid", __func__);
9790 return status;
9791 }
9792
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309793 if (NULL == pwextBuf)
9794 {
9795 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9796 __func__);
9797 return -EIO;
9798 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309799 cfg_param = pHddCtx->cfg_ini;
9800 pScanInfo = &pHddCtx->scan_info;
9801
Jeff Johnson295189b2012-06-20 16:38:30 -07009802#ifdef WLAN_BTAMP_FEATURE
9803 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009804 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009806 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 "%s: No scanning when AMP is on", __func__);
9808 return -EOPNOTSUPP;
9809 }
9810#endif
9811 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009812 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009814 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309815 "%s: Not scanning on device_mode = %s (%d)",
9816 __func__, hdd_device_modetoString(pAdapter->device_mode),
9817 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 return -EOPNOTSUPP;
9819 }
9820
9821 if (TRUE == pScanInfo->mScanPending)
9822 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309823 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9824 {
9825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9826 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009827 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 }
9829
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309830 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009831 //Channel and action frame is pending
9832 //Otherwise Cancel Remain On Channel and allow Scan
9833 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009834 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009835 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009837 return -EBUSY;
9838 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009839#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009840 /* if tdls disagree scan right now, return immediately.
9841 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9842 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9843 */
9844 status = wlan_hdd_tdls_scan_callback (pAdapter,
9845 wiphy,
9846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9847 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009848#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009849 request);
9850 if(status <= 0)
9851 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309852 if(!status)
9853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
9854 "scan rejected %d", __func__, status);
9855 else
9856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
9857 __func__, status);
9858
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009859 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009860 }
9861#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07009862
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
9864 {
9865 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08009866 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309868 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
9870 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309871 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 "%s: MAX TM Level Scan not allowed", __func__);
9873 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309874 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 }
9876 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
9877
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009878 /* Check if scan is allowed at this point of time.
9879 */
Ganesh Kondabattiniaeb7b772014-08-11 20:00:36 +05309880 if (hdd_isConnectionInProgress(pHddCtx, VOS_FALSE))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009881 {
9882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
9883 return -EBUSY;
9884 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309885
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 vos_mem_zero( &scanRequest, sizeof(scanRequest));
9887
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309888 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
9889 (int)request->n_ssids);
9890
Agarwal Ashish0335a322014-11-24 19:19:46 +05309891
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309892 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
9893 * Becasue of this, driver is assuming that this is not wildcard scan and so
9894 * is not aging out the scan results.
9895 */
9896 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309898 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309900
9901 if ((request->ssids) && (0 < request->n_ssids))
9902 {
9903 tCsrSSIDInfo *SsidInfo;
9904 int j;
9905 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
9906 /* Allocate num_ssid tCsrSSIDInfo structure */
9907 SsidInfo = scanRequest.SSIDs.SSIDList =
9908 ( tCsrSSIDInfo *)vos_mem_malloc(
9909 request->n_ssids*sizeof(tCsrSSIDInfo));
9910
9911 if(NULL == scanRequest.SSIDs.SSIDList)
9912 {
9913 hddLog(VOS_TRACE_LEVEL_ERROR,
9914 "%s: memory alloc failed SSIDInfo buffer", __func__);
9915 return -ENOMEM;
9916 }
9917
9918 /* copy all the ssid's and their length */
9919 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
9920 {
9921 /* get the ssid length */
9922 SsidInfo->SSID.length = request->ssids[j].ssid_len;
9923 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
9924 SsidInfo->SSID.length);
9925 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
9926 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
9927 j, SsidInfo->SSID.ssId);
9928 }
9929 /* set the scan type to active */
9930 scanRequest.scanType = eSIR_ACTIVE_SCAN;
9931 }
9932 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9935 TRACE_CODE_HDD_CFG80211_SCAN,
9936 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 /* set the scan type to active */
9938 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309940 else
9941 {
9942 /*Set the scan type to default type, in this case it is ACTIVE*/
9943 scanRequest.scanType = pScanInfo->scan_mode;
9944 }
9945 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
9946 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 /* set BSSType to default type */
9949 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
9950
9951 /*TODO: scan the requested channels only*/
9952
9953 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309954 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309956 hddLog(VOS_TRACE_LEVEL_WARN,
9957 "No of Scan Channels exceeded limit: %d", request->n_channels);
9958 request->n_channels = MAX_CHANNEL;
9959 }
9960
9961 hddLog(VOS_TRACE_LEVEL_INFO,
9962 "No of Scan Channels: %d", request->n_channels);
9963
9964
9965 if( request->n_channels )
9966 {
9967 char chList [(request->n_channels*5)+1];
9968 int len;
9969 channelList = vos_mem_malloc( request->n_channels );
9970 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05309971 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309972 hddLog(VOS_TRACE_LEVEL_ERROR,
9973 "%s: memory alloc failed channelList", __func__);
9974 status = -ENOMEM;
9975 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05309976 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309977
9978 for( i = 0, len = 0; i < request->n_channels ; i++ )
9979 {
9980 channelList[i] = request->channels[i]->hw_value;
9981 len += snprintf(chList+len, 5, "%d ", channelList[i]);
9982 }
9983
Nirav Shah20ac06f2013-12-12 18:14:06 +05309984 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309985 "Channel-List: %s ", chList);
9986 }
c_hpothu53512302014-04-15 18:49:53 +05309987
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309988 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
9989 scanRequest.ChannelInfo.ChannelList = channelList;
9990
9991 /* set requestType to full scan */
9992 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9993
Agarwal Ashish0335a322014-11-24 19:19:46 +05309994 /* if there is back to back scan happening in driver with in
9995 * nDeferScanTimeInterval interval driver should defer new scan request
9996 * and should provide last cached scan results instead of new channel list.
9997 * This rule is not applicable if scan is p2p scan.
9998 * This condition will work only in case when last request no of channels
9999 * and channels are exactly same as new request.
10000 */
10001 if (pScanInfo->last_scan_timestamp !=0 &&
10002 (FALSE == request->no_cck) && // no_cck is set during p2p find.
10003 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10004 {
10005 if (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels &&
10006 vos_mem_compare(pScanInfo->last_scan_channelList,
10007 channelList, pScanInfo->last_scan_numChannels))
10008 {
10009 hddLog(VOS_TRACE_LEVEL_WARN,
10010 " New and old station scan time differ is less then %u",
10011 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10012
10013 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
10014 pAdapter);
10015
10016 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddie7a49d32015-02-11 18:54:33 +053010017 "Return old cached scan as all channels and no of channels are same");
10018
Agarwal Ashish0335a322014-11-24 19:19:46 +053010019 if (0 > ret)
Masti, Narayanraddie7a49d32015-02-11 18:54:33 +053010020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashish0335a322014-11-24 19:19:46 +053010021
10022 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddie7a49d32015-02-11 18:54:33 +053010023
10024 status = eHAL_STATUS_SUCCESS;
10025 goto free_mem;
10026 }
Agarwal Ashish0335a322014-11-24 19:19:46 +053010027 }
10028
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010029 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10030 * search (Flush on both full scan and social scan but not on single
10031 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10032 */
10033
10034 /* Supplicant does single channel scan after 8-way handshake
10035 * and in that case driver shoudnt flush scan results. If
10036 * driver flushes the scan results here and unfortunately if
10037 * the AP doesnt respond to our probe req then association
10038 * fails which is not desired
10039 */
10040
10041 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10042 {
10043 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10044 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10045 pAdapter->sessionId );
10046 }
10047
10048 if( request->ie_len )
10049 {
10050 /* save this for future association (join requires this) */
10051 /*TODO: Array needs to be converted to dynamic allocation,
10052 * as multiple ie.s can be sent in cfg80211_scan_request structure
10053 * CR 597966
10054 */
10055 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10056 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10057 pScanInfo->scanAddIE.length = request->ie_len;
10058
10059 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10060 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10061 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010063 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010065 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10066 memcpy( pwextBuf->roamProfile.addIEScan,
10067 request->ie, request->ie_len);
10068 }
10069 else
10070 {
10071 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10072 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 }
10074
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010075 }
10076 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10077 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10078
10079 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10080 request->ie_len);
10081 if (pP2pIe != NULL)
10082 {
10083#ifdef WLAN_FEATURE_P2P_DEBUG
10084 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10085 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10086 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010087 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010088 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10089 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10090 "Go nego completed to Connection is started");
10091 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10092 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010093 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010094 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10095 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010097 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10098 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10099 "Disconnected state to Connection is started");
10100 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10101 "for 4way Handshake");
10102 }
10103#endif
10104
10105 /* no_cck will be set during p2p find to disable 11b rates */
10106 if(TRUE == request->no_cck)
10107 {
10108 hddLog(VOS_TRACE_LEVEL_INFO,
10109 "%s: This is a P2P Search", __func__);
10110 scanRequest.p2pSearch = 1;
10111
10112 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010113 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010114 /* set requestType to P2P Discovery */
10115 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10116 }
10117
10118 /*
10119 Skip Dfs Channel in case of P2P Search
10120 if it is set in ini file
10121 */
10122 if(cfg_param->skipDfsChnlInP2pSearch)
10123 {
10124 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010125 }
10126 else
10127 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010128 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010130
Agarwal Ashish4f616132013-12-30 23:32:50 +053010131 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
10133 }
10134
10135 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10136
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010137 /* acquire the wakelock to avoid the apps suspend during the scan. To
10138 * address the following issues.
10139 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10140 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10141 * for long time, this result in apps running at full power for long time.
10142 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10143 * be stuck in full power because of resume BMPS
10144 */
10145 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010146
Nirav Shah20ac06f2013-12-12 18:14:06 +053010147 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10148 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010149 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10150 scanRequest.requestType, scanRequest.scanType,
10151 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010152 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10153
Jeff Johnsone7245742012-09-05 17:12:55 -070010154 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 pAdapter->sessionId, &scanRequest, &scanId,
10156 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010157
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 if (eHAL_STATUS_SUCCESS != status)
10159 {
10160 hddLog(VOS_TRACE_LEVEL_ERROR,
10161 "%s: sme_ScanRequest returned error %d", __func__, status);
10162 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010163 if(eHAL_STATUS_RESOURCES == status)
10164 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10166 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010167 status = -EBUSY;
10168 } else {
10169 status = -EIO;
10170 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010171 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 goto free_mem;
10173 }
10174
10175 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant86ac0a52014-10-21 16:07:48 +053010176 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 pAdapter->request = request;
10178 pScanInfo->scanId = scanId;
10179
10180 complete(&pScanInfo->scan_req_completion_event);
10181
10182free_mem:
10183 if( scanRequest.SSIDs.SSIDList )
10184 {
10185 vos_mem_free(scanRequest.SSIDs.SSIDList);
10186 }
10187
10188 if( channelList )
10189 vos_mem_free( channelList );
10190
10191 EXIT();
10192
10193 return status;
10194}
10195
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010196int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10197#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10198 struct net_device *dev,
10199#endif
10200 struct cfg80211_scan_request *request)
10201{
10202 int ret;
10203
10204 vos_ssr_protect(__func__);
10205 ret = __wlan_hdd_cfg80211_scan(wiphy,
10206#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10207 dev,
10208#endif
10209 request);
10210 vos_ssr_unprotect(__func__);
10211
10212 return ret;
10213}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010214
10215void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10216{
10217 v_U8_t iniDot11Mode =
10218 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10219 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10220
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010221 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10222 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010223 switch ( iniDot11Mode )
10224 {
10225 case eHDD_DOT11_MODE_AUTO:
10226 case eHDD_DOT11_MODE_11ac:
10227 case eHDD_DOT11_MODE_11ac_ONLY:
10228#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010229 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10230 sme_IsFeatureSupportedByFW(DOT11AC) )
10231 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10232 else
10233 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010234#else
10235 hddDot11Mode = eHDD_DOT11_MODE_11n;
10236#endif
10237 break;
10238 case eHDD_DOT11_MODE_11n:
10239 case eHDD_DOT11_MODE_11n_ONLY:
10240 hddDot11Mode = eHDD_DOT11_MODE_11n;
10241 break;
10242 default:
10243 hddDot11Mode = iniDot11Mode;
10244 break;
10245 }
10246 /* This call decides required channel bonding mode */
10247 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
10248 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10249 operationChannel);
10250}
10251
Jeff Johnson295189b2012-06-20 16:38:30 -070010252/*
10253 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010254 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010256int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010257 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010258{
10259 int status = 0;
10260 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 v_U32_t roamId;
10263 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 eCsrAuthType RSNAuthType;
10265
10266 ENTER();
10267
10268 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10270
10271 status = wlan_hdd_validate_context(pHddCtx);
10272 if (status)
10273 {
10274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10275 "%s: HDD context is not valid!", __func__);
10276 return status;
10277 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010278
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10280 {
10281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10282 return -EINVAL;
10283 }
10284
10285 pRoamProfile = &pWextState->roamProfile;
10286
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010287 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010289 hdd_station_ctx_t *pHddStaCtx;
10290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010291
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010292 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10294 {
10295 /*QoS not enabled in cfg file*/
10296 pRoamProfile->uapsd_mask = 0;
10297 }
10298 else
10299 {
10300 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010301 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10303 }
10304
10305 pRoamProfile->SSIDs.numOfSSIDs = 1;
10306 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10307 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010308 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10310 ssid, ssid_len);
10311
10312 if (bssid)
10313 {
10314 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10315 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10316 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010317 /* Save BSSID in seperate variable as well, as RoamProfile
10318 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 case of join failure we should send valid BSSID to supplicant
10320 */
10321 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10322 WNI_CFG_BSSID_LEN);
10323 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010324 else
10325 {
10326 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10327 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010328
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010329 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10330 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10332 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010333 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 /*set gen ie*/
10335 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10336 /*set auth*/
10337 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010339#ifdef FEATURE_WLAN_WAPI
10340 if (pAdapter->wapi_info.nWapiMode)
10341 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010342 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 switch (pAdapter->wapi_info.wapiAuthMode)
10344 {
10345 case WAPI_AUTH_MODE_PSK:
10346 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010347 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010348 pAdapter->wapi_info.wapiAuthMode);
10349 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10350 break;
10351 }
10352 case WAPI_AUTH_MODE_CERT:
10353 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010354 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 pAdapter->wapi_info.wapiAuthMode);
10356 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10357 break;
10358 }
10359 } // End of switch
10360 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10361 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10362 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010363 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 pRoamProfile->AuthType.numEntries = 1;
10365 pRoamProfile->EncryptionType.numEntries = 1;
10366 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10367 pRoamProfile->mcEncryptionType.numEntries = 1;
10368 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10369 }
10370 }
10371#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010372#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010373 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010374 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10375 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10376 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010377 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10378 sizeof (tSirGtkOffloadParams));
10379 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010380 }
10381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 pRoamProfile->csrPersona = pAdapter->device_mode;
10383
Jeff Johnson32d95a32012-09-10 13:15:23 -070010384 if( operatingChannel )
10385 {
10386 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10387 pRoamProfile->ChannelInfo.numOfChannels = 1;
10388 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010389 else
10390 {
10391 pRoamProfile->ChannelInfo.ChannelList = NULL;
10392 pRoamProfile->ChannelInfo.numOfChannels = 0;
10393 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010394 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10395 {
10396 hdd_select_cbmode(pAdapter,operatingChannel);
10397 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010398
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010399 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10400 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010401 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010402 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010403 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10404 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010405 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10406 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010407 {
10408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10409 "%s: Set HDD connState to eConnectionState_Connecting",
10410 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010411 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10412 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010413 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010414 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 pAdapter->sessionId, pRoamProfile, &roamId);
10416
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010417 if ((eHAL_STATUS_SUCCESS != status) &&
10418 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10419 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010420
10421 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10423 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10424 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010425 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010426 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010427 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010428
10429 pRoamProfile->ChannelInfo.ChannelList = NULL;
10430 pRoamProfile->ChannelInfo.numOfChannels = 0;
10431
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 }
10433 else
10434 {
10435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10436 return -EINVAL;
10437 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010438 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 return status;
10440}
10441
10442/*
10443 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10444 * This function is used to set the authentication type (OPEN/SHARED).
10445 *
10446 */
10447static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10448 enum nl80211_auth_type auth_type)
10449{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010450 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10452
10453 ENTER();
10454
10455 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010456 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010459 hddLog(VOS_TRACE_LEVEL_INFO,
10460 "%s: set authentication type to AUTOSWITCH", __func__);
10461 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10462 break;
10463
10464 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010465#ifdef WLAN_FEATURE_VOWIFI_11R
10466 case NL80211_AUTHTYPE_FT:
10467#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010468 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 "%s: set authentication type to OPEN", __func__);
10470 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10471 break;
10472
10473 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010474 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 "%s: set authentication type to SHARED", __func__);
10476 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10477 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010478#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010480 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 "%s: set authentication type to CCKM WPA", __func__);
10482 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10483 break;
10484#endif
10485
10486
10487 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010488 hddLog(VOS_TRACE_LEVEL_ERROR,
10489 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 auth_type);
10491 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10492 return -EINVAL;
10493 }
10494
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010495 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 pHddStaCtx->conn_info.authType;
10497 return 0;
10498}
10499
10500/*
10501 * FUNCTION: wlan_hdd_set_akm_suite
10502 * This function is used to set the key mgmt type(PSK/8021x).
10503 *
10504 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 u32 key_mgmt
10507 )
10508{
10509 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10510 ENTER();
Abhishek Singh2a2be6c2014-09-25 17:22:04 +053010511 /* Should be in ieee802_11_defs.h */
10512#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10513#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 /*set key mgmt type*/
10515 switch(key_mgmt)
10516 {
10517 case WLAN_AKM_SUITE_PSK:
Abhishek Singh2a2be6c2014-09-25 17:22:04 +053010518 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010519#ifdef WLAN_FEATURE_VOWIFI_11R
10520 case WLAN_AKM_SUITE_FT_PSK:
10521#endif
10522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 __func__);
10524 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10525 break;
10526
10527 case WLAN_AKM_SUITE_8021X:
Abhishek Singh2a2be6c2014-09-25 17:22:04 +053010528 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010529#ifdef WLAN_FEATURE_VOWIFI_11R
10530 case WLAN_AKM_SUITE_FT_8021X:
10531#endif
10532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 __func__);
10534 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10535 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010536#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010537#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10538#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10539 case WLAN_AKM_SUITE_CCKM:
10540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10541 __func__);
10542 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10543 break;
10544#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010545#ifndef WLAN_AKM_SUITE_OSEN
10546#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10547 case WLAN_AKM_SUITE_OSEN:
10548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10549 __func__);
10550 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10551 break;
10552#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010553
10554 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010555 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 __func__, key_mgmt);
10557 return -EINVAL;
10558
10559 }
10560 return 0;
10561}
10562
10563/*
10564 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010565 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 * (NONE/WEP40/WEP104/TKIP/CCMP).
10567 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010568static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10569 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010570 bool ucast
10571 )
10572{
10573 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010574 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10576
10577 ENTER();
10578
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010579 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 __func__, cipher);
10583 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10584 }
10585 else
10586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010587
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010589 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010590 {
10591 case IW_AUTH_CIPHER_NONE:
10592 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10593 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010594
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010596 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010598
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010600 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010601 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010602
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 case WLAN_CIPHER_SUITE_TKIP:
10604 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10605 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010606
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 case WLAN_CIPHER_SUITE_CCMP:
10608 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10609 break;
10610#ifdef FEATURE_WLAN_WAPI
10611 case WLAN_CIPHER_SUITE_SMS4:
10612 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10613 break;
10614#endif
10615
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010616#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 case WLAN_CIPHER_SUITE_KRK:
10618 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10619 break;
10620#endif
10621 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 __func__, cipher);
10624 return -EOPNOTSUPP;
10625 }
10626 }
10627
10628 if (ucast)
10629 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 __func__, encryptionType);
10632 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10633 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010634 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 encryptionType;
10636 }
10637 else
10638 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010640 __func__, encryptionType);
10641 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10642 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10643 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10644 }
10645
10646 return 0;
10647}
10648
10649
10650/*
10651 * FUNCTION: wlan_hdd_cfg80211_set_ie
10652 * This function is used to parse WPA/RSN IE's.
10653 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010654int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10655 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 size_t ie_len
10657 )
10658{
10659 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10660 u8 *genie = ie;
10661 v_U16_t remLen = ie_len;
10662#ifdef FEATURE_WLAN_WAPI
10663 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10664 u16 *tmp;
10665 v_U16_t akmsuiteCount;
10666 int *akmlist;
10667#endif
10668 ENTER();
10669
10670 /* clear previous assocAddIE */
10671 pWextState->assocAddIE.length = 0;
10672 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010673 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010674
10675 while (remLen >= 2)
10676 {
10677 v_U16_t eLen = 0;
10678 v_U8_t elementId;
10679 elementId = *genie++;
10680 eLen = *genie++;
10681 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010682
Arif Hussain6d2a3322013-11-17 19:50:10 -080010683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010685
10686 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010688 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010689 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 -070010690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010691 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 "%s: Invalid WPA IE", __func__);
10693 return -EINVAL;
10694 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010695 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 {
10697 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010698 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010699 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010700
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10702 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010703 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10704 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 VOS_ASSERT(0);
10706 return -ENOMEM;
10707 }
10708 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10709 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10710 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010711
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10713 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10714 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10715 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010716 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10717 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010718 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10719 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10720 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10721 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10722 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10723 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010724 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010725 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 {
10727 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010728 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010730
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10732 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010733 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10734 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010735 VOS_ASSERT(0);
10736 return -ENOMEM;
10737 }
10738 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10739 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10740 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741
Jeff Johnson295189b2012-06-20 16:38:30 -070010742 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10743 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010745#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010746 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10747 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010748 /*Consider WFD IE, only for P2P Client */
10749 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10750 {
10751 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010752 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010753 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010754
Jeff Johnson295189b2012-06-20 16:38:30 -070010755 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10756 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010757 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10758 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010759 VOS_ASSERT(0);
10760 return -ENOMEM;
10761 }
10762 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10763 // WPS IE + P2P IE + WFD IE
10764 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10765 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010766
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10768 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10769 }
10770#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010771 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010773 HS20_OUI_TYPE_SIZE)) )
10774 {
10775 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010777 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010778
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010779 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10780 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010781 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10782 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010783 VOS_ASSERT(0);
10784 return -ENOMEM;
10785 }
10786 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10787 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010788
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010789 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10790 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10791 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010792 /* Appending OSEN Information Element in Assiciation Request */
10793 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10794 OSEN_OUI_TYPE_SIZE)) )
10795 {
10796 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10797 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10798 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010799
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010800 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10801 {
10802 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10803 "Need bigger buffer space");
10804 VOS_ASSERT(0);
10805 return -ENOMEM;
10806 }
10807 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10808 pWextState->assocAddIE.length += eLen + 2;
10809
10810 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10811 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10812 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10813 }
10814
10815 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010816 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10817
10818 /* populating as ADDIE in beacon frames */
10819 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10820 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10821 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10822 {
10823 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10824 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10825 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10826 {
10827 hddLog(LOGE,
10828 "Coldn't pass "
10829 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10830 }
10831 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
10832 else
10833 hddLog(LOGE,
10834 "Could not pass on "
10835 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
10836
10837 /* IBSS mode doesn't contain params->proberesp_ies still
10838 beaconIE's need to be populated in probe response frames */
10839 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
10840 {
10841 u16 rem_probe_resp_ie_len = eLen + 2;
10842 u8 probe_rsp_ie_len[3] = {0};
10843 u8 counter = 0;
10844
10845 /* Check Probe Resp Length if it is greater then 255 then
10846 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
10847 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
10848 not able Store More then 255 bytes into One Variable */
10849
10850 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10851 {
10852 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10853 {
10854 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10855 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10856 }
10857 else
10858 {
10859 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10860 rem_probe_resp_ie_len = 0;
10861 }
10862 }
10863
10864 rem_probe_resp_ie_len = 0;
10865
10866 if (probe_rsp_ie_len[0] > 0)
10867 {
10868 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10869 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
10870 (tANI_U8*)(genie - 2),
10871 probe_rsp_ie_len[0], NULL,
10872 eANI_BOOLEAN_FALSE)
10873 == eHAL_STATUS_FAILURE)
10874 {
10875 hddLog(LOGE,
10876 "Could not pass"
10877 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
10878 }
10879 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10880 }
10881
10882 if (probe_rsp_ie_len[1] > 0)
10883 {
10884 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10885 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
10886 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10887 probe_rsp_ie_len[1], NULL,
10888 eANI_BOOLEAN_FALSE)
10889 == eHAL_STATUS_FAILURE)
10890 {
10891 hddLog(LOGE,
10892 "Could not pass"
10893 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
10894 }
10895 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10896 }
10897
10898 if (probe_rsp_ie_len[2] > 0)
10899 {
10900 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10901 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
10902 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
10903 probe_rsp_ie_len[2], NULL,
10904 eANI_BOOLEAN_FALSE)
10905 == eHAL_STATUS_FAILURE)
10906 {
10907 hddLog(LOGE,
10908 "Could not pass"
10909 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
10910 }
10911 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10912 }
10913
10914 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10915 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10916 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10917 {
10918 hddLog(LOGE,
10919 "Could not pass"
10920 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
10921 }
10922 }
10923 else
10924 {
10925 // Reset WNI_CFG_PROBE_RSP Flags
10926 wlan_hdd_reset_prob_rspies(pAdapter);
10927
10928 hddLog(VOS_TRACE_LEVEL_INFO,
10929 "%s: No Probe Response IE received in set beacon",
10930 __func__);
10931 }
10932 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 break;
10934 case DOT11F_EID_RSN:
10935 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
10936 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10937 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
10938 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
10939 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
10940 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010941 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
10942 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010943 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010944 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010945 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010946 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010947
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010948 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10949 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010950 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10951 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010952 VOS_ASSERT(0);
10953 return -ENOMEM;
10954 }
10955 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10956 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010958 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10959 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10960 break;
10961 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010962#ifdef FEATURE_WLAN_WAPI
10963 case WLAN_EID_WAPI:
10964 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010965 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 pAdapter->wapi_info.nWapiMode);
10967 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010968 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070010969 akmsuiteCount = WPA_GET_LE16(tmp);
10970 tmp = tmp + 1;
10971 akmlist = (int *)(tmp);
10972 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
10973 {
10974 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
10975 }
10976 else
10977 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010978 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 VOS_ASSERT(0);
10980 return -EINVAL;
10981 }
10982
10983 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
10984 {
10985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010986 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010988 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010990 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010992 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
10994 }
10995 break;
10996#endif
10997 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010998 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011000 /* when Unknown IE is received we should break and continue
11001 * to the next IE in the buffer instead we were returning
11002 * so changing this to break */
11003 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 }
11005 genie += eLen;
11006 remLen -= eLen;
11007 }
11008 EXIT();
11009 return 0;
11010}
11011
11012/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011013 * FUNCTION: hdd_isWPAIEPresent
11014 * Parse the received IE to find the WPA IE
11015 *
11016 */
11017static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11018{
11019 v_U8_t eLen = 0;
11020 v_U16_t remLen = ie_len;
11021 v_U8_t elementId = 0;
11022
11023 while (remLen >= 2)
11024 {
11025 elementId = *ie++;
11026 eLen = *ie++;
11027 remLen -= 2;
11028 if (eLen > remLen)
11029 {
11030 hddLog(VOS_TRACE_LEVEL_ERROR,
11031 "%s: IE length is wrong %d", __func__, eLen);
11032 return FALSE;
11033 }
11034 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11035 {
11036 /* OUI - 0x00 0X50 0XF2
11037 WPA Information Element - 0x01
11038 WPA version - 0x01*/
11039 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11040 return TRUE;
11041 }
11042 ie += eLen;
11043 remLen -= eLen;
11044 }
11045 return FALSE;
11046}
11047
11048/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011050 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 * parameters during connect operation.
11052 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011053int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 struct cfg80211_connect_params *req
11055 )
11056{
11057 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011058 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011059 ENTER();
11060
11061 /*set wpa version*/
11062 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11063
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011064 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011066 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011067 {
11068 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11069 }
11070 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11071 {
11072 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11073 }
11074 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075
11076 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 pWextState->wpaVersion);
11078
11079 /*set authentication type*/
11080 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11081
11082 if (0 > status)
11083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011084 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011085 "%s: failed to set authentication type ", __func__);
11086 return status;
11087 }
11088
11089 /*set key mgmt type*/
11090 if (req->crypto.n_akm_suites)
11091 {
11092 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11093 if (0 > status)
11094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 __func__);
11097 return status;
11098 }
11099 }
11100
11101 /*set pairwise cipher type*/
11102 if (req->crypto.n_ciphers_pairwise)
11103 {
11104 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11105 req->crypto.ciphers_pairwise[0], true);
11106 if (0 > status)
11107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011108 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 "%s: failed to set unicast cipher type", __func__);
11110 return status;
11111 }
11112 }
11113 else
11114 {
11115 /*Reset previous cipher suite to none*/
11116 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11117 if (0 > status)
11118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011119 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011120 "%s: failed to set unicast cipher type", __func__);
11121 return status;
11122 }
11123 }
11124
11125 /*set group cipher type*/
11126 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11127 false);
11128
11129 if (0 > status)
11130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 __func__);
11133 return status;
11134 }
11135
Chet Lanctot186b5732013-03-18 10:26:30 -070011136#ifdef WLAN_FEATURE_11W
11137 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11138#endif
11139
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11141 if (req->ie_len)
11142 {
11143 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11144 if ( 0 > status)
11145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 __func__);
11148 return status;
11149 }
11150 }
11151
11152 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011153 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 {
11155 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11156 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11157 )
11158 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011159 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 __func__);
11164 return -EOPNOTSUPP;
11165 }
11166 else
11167 {
11168 u8 key_len = req->key_len;
11169 u8 key_idx = req->key_idx;
11170
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 && (CSR_MAX_NUM_KEY > key_idx)
11173 )
11174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011175 hddLog(VOS_TRACE_LEVEL_INFO,
11176 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 __func__, key_idx, key_len);
11178 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011181 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 (u8)key_len;
11183 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11184 }
11185 }
11186 }
11187 }
11188
11189 return status;
11190}
11191
11192/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011193 * FUNCTION: wlan_hdd_try_disconnect
11194 * This function is used to disconnect from previous
11195 * connection
11196 */
11197static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11198{
11199 long ret = 0;
11200 hdd_station_ctx_t *pHddStaCtx;
11201 eMib_dot11DesiredBssType connectedBssType;
11202
11203 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11204
11205 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11206
11207 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11208 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11209 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11210 {
11211 /* Issue disconnect to CSR */
11212 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11213 if( eHAL_STATUS_SUCCESS ==
11214 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11215 pAdapter->sessionId,
11216 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11217 {
11218 ret = wait_for_completion_interruptible_timeout(
11219 &pAdapter->disconnect_comp_var,
11220 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11221 if (0 >= ret)
11222 {
11223 hddLog(LOGE, FL("Failed to receive disconnect event"));
11224 return -EALREADY;
11225 }
11226 }
11227 }
11228 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11229 {
11230 ret = wait_for_completion_interruptible_timeout(
11231 &pAdapter->disconnect_comp_var,
11232 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11233 if (0 >= ret)
11234 {
11235 hddLog(LOGE, FL("Failed to receive disconnect event"));
11236 return -EALREADY;
11237 }
11238 }
11239
11240 return 0;
11241}
11242
11243/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011244 * FUNCTION: __wlan_hdd_cfg80211_connect
11245 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011247static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011248 struct net_device *ndev,
11249 struct cfg80211_connect_params *req
11250 )
11251{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011252 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011255 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011258
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11260 TRACE_CODE_HDD_CFG80211_CONNECT,
11261 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011262 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011263 "%s: device_mode = %s (%d)", __func__,
11264 hdd_device_modetoString(pAdapter->device_mode),
11265 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011266
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011268 if (!pHddCtx)
11269 {
11270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11271 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011272 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011273 }
11274
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011275 status = wlan_hdd_validate_context(pHddCtx);
11276
11277 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11280 "%s: HDD context is not valid", __func__);
11281 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 }
11283
Agarwal Ashish51325b52014-06-16 16:50:49 +053011284 if (vos_max_concurrent_connections_reached()) {
11285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11286 return -ECONNREFUSED;
11287 }
11288
Jeff Johnson295189b2012-06-20 16:38:30 -070011289#ifdef WLAN_BTAMP_FEATURE
11290 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011293 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011295 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 }
11297#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011298
11299 //If Device Mode is Station Concurrent Sessions Exit BMps
11300 //P2P Mode will be taken care in Open/close adapter
11301 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011302 (vos_concurrent_open_sessions_running())) {
11303 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11304 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011305 }
11306
11307 /*Try disconnecting if already in connected state*/
11308 status = wlan_hdd_try_disconnect(pAdapter);
11309 if ( 0 > status)
11310 {
11311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11312 " connection"));
11313 return -EALREADY;
11314 }
11315
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011318
11319 if ( 0 > status)
11320 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 __func__);
11323 return status;
11324 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011325 if ( req->channel )
11326 {
11327 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11328 req->ssid_len, req->bssid,
11329 req->channel->hw_value);
11330 }
11331 else
11332 {
11333 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011334 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011336
11337 if (0 > status)
11338 {
11339 //ReEnable BMPS if disabled
11340 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11341 (NULL != pHddCtx))
11342 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011343 if (pHddCtx->hdd_wlan_suspended)
11344 {
11345 hdd_set_pwrparams(pHddCtx);
11346 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 //ReEnable Bmps and Imps back
11348 hdd_enable_bmps_imps(pHddCtx);
11349 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 return status;
11352 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011353 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 EXIT();
11355 return status;
11356}
11357
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011358static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11359 struct net_device *ndev,
11360 struct cfg80211_connect_params *req)
11361{
11362 int ret;
11363 vos_ssr_protect(__func__);
11364 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11365 vos_ssr_unprotect(__func__);
11366
11367 return ret;
11368}
Jeff Johnson295189b2012-06-20 16:38:30 -070011369
11370/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011371 * FUNCTION: wlan_hdd_disconnect
11372 * This function is used to issue a disconnect request to SME
11373 */
11374int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11375{
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011376 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011377 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011378 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011379 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011380
11381 status = wlan_hdd_validate_context(pHddCtx);
11382
11383 if (0 != status)
11384 {
11385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11386 "%s: HDD context is not valid", __func__);
11387 return status;
11388 }
11389
11390 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011391
Agarwal Ashish47d18112014-08-04 19:55:07 +053011392 /* Need to apply spin lock before decreasing active sessions
11393 * as there can be chance for double decrement if context switch
11394 * Calls hdd_DisConnectHandler.
11395 */
11396
11397 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011398 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11399 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011400 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11401 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011402 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11403 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011404
Abhishek Singhf4669da2014-05-26 15:07:49 +053011405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011406 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11407
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011408 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011409
Mihir Shete182a0b22014-08-18 16:08:48 +053011410 /*
11411 * stop tx queues before deleting STA/BSS context from the firmware.
11412 * tx has to be disabled because the firmware can get busy dropping
11413 * the tx frames after BSS/STA has been deleted and will not send
11414 * back a response resulting in WDI timeout
11415 */
11416 netif_tx_disable(pAdapter->dev);
11417 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011418
Mihir Shete182a0b22014-08-18 16:08:48 +053011419 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011420 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11421 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011422 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11423 {
11424 hddLog(VOS_TRACE_LEVEL_INFO,
11425 FL("status = %d, already disconnected"),
11426 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011427
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011428 }
11429 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011430 {
11431 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011432 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011433 __func__, (int)status );
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011434 result = -EINVAL;
11435 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011436 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011437 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011438 &pAdapter->disconnect_comp_var,
11439 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011440 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011441 {
11442 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011443 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011444 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011445 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011446 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011447 {
11448 hddLog(VOS_TRACE_LEVEL_ERROR,
11449 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011450 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011451 }
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011452disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11454 FL("Set HDD connState to eConnectionState_NotConnected"));
11455 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11456
Abhishek Singheeb75ee2014-11-27 12:10:10 +053011457 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011458}
11459
11460
11461/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011462 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 * This function is used to issue a disconnect request to SME
11464 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011465static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 struct net_device *dev,
11467 u16 reason
11468 )
11469{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011471 tCsrRoamProfile *pRoamProfile =
11472 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011473 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011474 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11475 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011476#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011477 tANI_U8 staIdx;
11478#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011481
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11483 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11484 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011485 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11486 __func__, hdd_device_modetoString(pAdapter->device_mode),
11487 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011488
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011489 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11490 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011492 status = wlan_hdd_validate_context(pHddCtx);
11493
11494 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11497 "%s: HDD context is not valid", __func__);
11498 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011500
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 if (NULL != pRoamProfile)
11502 {
11503 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011504 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11505 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011507 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011509 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 switch(reason)
11511 {
11512 case WLAN_REASON_MIC_FAILURE:
11513 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11514 break;
11515
11516 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11517 case WLAN_REASON_DISASSOC_AP_BUSY:
11518 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11519 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11520 break;
11521
11522 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11523 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011524 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11526 break;
11527
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 default:
11529 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11530 break;
11531 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011532 pScanInfo = &pHddCtx->scan_info;
11533 if (pScanInfo->mScanPending)
11534 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011535 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011536 "Aborting Scan");
Kaushik, Sushant86ac0a52014-10-21 16:07:48 +053011537 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011538 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011539 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011540
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011541#ifdef FEATURE_WLAN_TDLS
11542 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011543 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011544 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011545 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11546 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011547 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011548 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011549 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011550 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011551 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011552 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011553 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011554 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011555 pAdapter->sessionId,
11556 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011557 }
11558 }
11559#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011560 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011561 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11562 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 {
11564 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011565 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 __func__, (int)status );
11567 return -EINVAL;
11568 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011570 else
11571 {
11572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11573 "called while in %d state", __func__,
11574 pHddStaCtx->conn_info.connState);
11575 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 }
11577 else
11578 {
11579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11580 }
11581
11582 return status;
11583}
11584
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011585static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11586 struct net_device *dev,
11587 u16 reason
11588 )
11589{
11590 int ret;
11591 vos_ssr_protect(__func__);
11592 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11593 vos_ssr_unprotect(__func__);
11594
11595 return ret;
11596}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011597
Jeff Johnson295189b2012-06-20 16:38:30 -070011598/*
11599 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011600 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 * settings in IBSS mode.
11602 */
11603static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 struct cfg80211_ibss_params *params
11606 )
11607{
11608 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011609 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011610 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11611 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011612
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 ENTER();
11614
11615 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011616 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011617
11618 if (params->ie_len && ( NULL != params->ie) )
11619 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011620 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11621 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 {
11623 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11624 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11625 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011626 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011628 tDot11fIEWPA dot11WPAIE;
11629 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011630 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011631
Wilson Yang00256342013-10-10 23:13:38 -070011632 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011633 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11634 params->ie_len, DOT11F_EID_WPA);
11635 if ( NULL != ie )
11636 {
11637 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11638 // Unpack the WPA IE
11639 //Skip past the EID byte and length byte - and four byte WiFi OUI
11640 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11641 &ie[2+4],
11642 ie[1] - 4,
11643 &dot11WPAIE);
11644 /*Extract the multicast cipher, the encType for unicast
11645 cipher for wpa-none is none*/
11646 encryptionType =
11647 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11648 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011650
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11652
11653 if (0 > status)
11654 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 __func__);
11657 return status;
11658 }
11659 }
11660
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011661 pWextState->roamProfile.AuthType.authType[0] =
11662 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11664
11665 if (params->privacy)
11666 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 /* Security enabled IBSS, At this time there is no information available
11668 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011670 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011671 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011672 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 *enable privacy bit in beacons */
11674
11675 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11676 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011677 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11678 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11680 pWextState->roamProfile.EncryptionType.numEntries = 1;
11681 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 return status;
11683}
11684
11685/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011686 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011687 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011689static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 struct net_device *dev,
11691 struct cfg80211_ibss_params *params
11692 )
11693{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11696 tCsrRoamProfile *pRoamProfile;
11697 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011698 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011699 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11700 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011701
11702 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011703
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011704 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11705 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11706 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011708 "%s: device_mode = %s (%d)", __func__,
11709 hdd_device_modetoString(pAdapter->device_mode),
11710 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011711
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011712 status = wlan_hdd_validate_context(pHddCtx);
11713
11714 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11717 "%s: HDD context is not valid", __func__);
11718 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 }
11720
11721 if (NULL == pWextState)
11722 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011723 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 __func__);
11725 return -EIO;
11726 }
11727
Agarwal Ashish51325b52014-06-16 16:50:49 +053011728 if (vos_max_concurrent_connections_reached()) {
11729 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11730 return -ECONNREFUSED;
11731 }
11732
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011733 /*Try disconnecting if already in connected state*/
11734 status = wlan_hdd_try_disconnect(pAdapter);
11735 if ( 0 > status)
11736 {
11737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11738 " IBSS connection"));
11739 return -EALREADY;
11740 }
11741
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 pRoamProfile = &pWextState->roamProfile;
11743
11744 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011746 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011747 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 return -EINVAL;
11749 }
11750
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011751 /* BSSID is provided by upper layers hence no need to AUTO generate */
11752 if (NULL != params->bssid) {
11753 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11754 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11755 hddLog (VOS_TRACE_LEVEL_ERROR,
11756 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11757 return -EIO;
11758 }
11759 }
krunal sonie9002db2013-11-25 14:24:17 -080011760 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11761 {
11762 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11763 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11764 {
11765 hddLog (VOS_TRACE_LEVEL_ERROR,
11766 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11767 return -EIO;
11768 }
11769 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11770 if (!params->bssid)
11771 {
11772 hddLog (VOS_TRACE_LEVEL_ERROR,
11773 "%s:Failed memory allocation", __func__);
11774 return -EIO;
11775 }
11776 vos_mem_copy((v_U8_t *)params->bssid,
11777 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11778 VOS_MAC_ADDR_SIZE);
11779 alloc_bssid = VOS_TRUE;
11780 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011781
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011783 if (NULL !=
11784#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11785 params->chandef.chan)
11786#else
11787 params->channel)
11788#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 {
11790 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011791 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11792 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11793 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11794 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011795
11796 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011798 ieee80211_frequency_to_channel(
11799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11800 params->chandef.chan->center_freq);
11801#else
11802 params->channel->center_freq);
11803#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011804
11805 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11806 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11809 __func__);
11810 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011812
11813 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011815 if (channelNum == validChan[indx])
11816 {
11817 break;
11818 }
11819 }
11820 if (indx >= numChans)
11821 {
11822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 __func__, channelNum);
11824 return -EINVAL;
11825 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011826 /* Set the Operational Channel */
11827 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11828 channelNum);
11829 pRoamProfile->ChannelInfo.numOfChannels = 1;
11830 pHddStaCtx->conn_info.operationChannel = channelNum;
11831 pRoamProfile->ChannelInfo.ChannelList =
11832 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 }
11834
11835 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 if (status < 0)
11838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 __func__);
11841 return status;
11842 }
11843
11844 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011845 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011846 params->ssid_len, params->bssid,
11847 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011848
11849 if (0 > status)
11850 {
11851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
11852 return status;
11853 }
11854
krunal sonie9002db2013-11-25 14:24:17 -080011855 if (NULL != params->bssid &&
11856 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
11857 alloc_bssid == VOS_TRUE)
11858 {
11859 vos_mem_free(params->bssid);
11860 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 return 0;
11862}
11863
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011864static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
11865 struct net_device *dev,
11866 struct cfg80211_ibss_params *params
11867 )
11868{
11869 int ret = 0;
11870
11871 vos_ssr_protect(__func__);
11872 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
11873 vos_ssr_unprotect(__func__);
11874
11875 return ret;
11876}
11877
Jeff Johnson295189b2012-06-20 16:38:30 -070011878/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011879 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011880 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011882static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 struct net_device *dev
11884 )
11885{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011886 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011887 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11888 tCsrRoamProfile *pRoamProfile;
11889 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011890 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011891
11892 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011893
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11895 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
11896 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011897 status = wlan_hdd_validate_context(pHddCtx);
11898
11899 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011900 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11902 "%s: HDD context is not valid", __func__);
11903 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011904 }
11905
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011906 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
11907 hdd_device_modetoString(pAdapter->device_mode),
11908 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 if (NULL == pWextState)
11910 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011911 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011912 __func__);
11913 return -EIO;
11914 }
11915
11916 pRoamProfile = &pWextState->roamProfile;
11917
11918 /* Issue disconnect only if interface type is set to IBSS */
11919 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
11920 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011921 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 __func__);
11923 return -EINVAL;
11924 }
11925
11926 /* Issue Disconnect request */
11927 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11928 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
11929 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
11930
11931 return 0;
11932}
11933
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011934static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
11935 struct net_device *dev
11936 )
11937{
11938 int ret = 0;
11939
11940 vos_ssr_protect(__func__);
11941 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
11942 vos_ssr_unprotect(__func__);
11943
11944 return ret;
11945}
11946
Jeff Johnson295189b2012-06-20 16:38:30 -070011947/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011948 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 * This function is used to set the phy parameters
11950 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
11951 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011952static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 u32 changed)
11954{
11955 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
11956 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011957 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011958
11959 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11961 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
11962 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011963 status = wlan_hdd_validate_context(pHddCtx);
11964
11965 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11968 "%s: HDD context is not valid", __func__);
11969 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011970 }
11971
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
11973 {
11974 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
11975 WNI_CFG_RTS_THRESHOLD_STAMAX :
11976 wiphy->rts_threshold;
11977
11978 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011979 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011981 hddLog(VOS_TRACE_LEVEL_ERROR,
11982 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 __func__, rts_threshold);
11984 return -EINVAL;
11985 }
11986
11987 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
11988 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011989 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011991 hddLog(VOS_TRACE_LEVEL_ERROR,
11992 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 __func__, rts_threshold);
11994 return -EIO;
11995 }
11996
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011997 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011998 rts_threshold);
11999 }
12000
12001 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12002 {
12003 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12004 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12005 wiphy->frag_threshold;
12006
12007 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012010 hddLog(VOS_TRACE_LEVEL_ERROR,
12011 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 frag_threshold);
12013 return -EINVAL;
12014 }
12015
12016 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12017 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012018 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012020 hddLog(VOS_TRACE_LEVEL_ERROR,
12021 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 __func__, frag_threshold);
12023 return -EIO;
12024 }
12025
12026 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12027 frag_threshold);
12028 }
12029
12030 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12031 || (changed & WIPHY_PARAM_RETRY_LONG))
12032 {
12033 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12034 wiphy->retry_short :
12035 wiphy->retry_long;
12036
12037 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12038 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 __func__, retry_value);
12042 return -EINVAL;
12043 }
12044
12045 if (changed & WIPHY_PARAM_RETRY_SHORT)
12046 {
12047 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12048 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012049 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012051 hddLog(VOS_TRACE_LEVEL_ERROR,
12052 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 __func__, retry_value);
12054 return -EIO;
12055 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012056 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 __func__, retry_value);
12058 }
12059 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12060 {
12061 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12062 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012063 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012065 hddLog(VOS_TRACE_LEVEL_ERROR,
12066 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012067 __func__, retry_value);
12068 return -EIO;
12069 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012070 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012071 __func__, retry_value);
12072 }
12073 }
12074
12075 return 0;
12076}
12077
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012078static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12079 u32 changed)
12080{
12081 int ret;
12082
12083 vos_ssr_protect(__func__);
12084 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12085 vos_ssr_unprotect(__func__);
12086
12087 return ret;
12088}
12089
Jeff Johnson295189b2012-06-20 16:38:30 -070012090/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012091 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012092 * This function is used to set the txpower
12093 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012094static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012095#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12096 struct wireless_dev *wdev,
12097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012098#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012099 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012100#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012102#endif
12103 int dbm)
12104{
12105 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012106 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12108 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012109 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012110
12111 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12113 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12114 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012115 status = wlan_hdd_validate_context(pHddCtx);
12116
12117 if (0 != status)
12118 {
12119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12120 "%s: HDD context is not valid", __func__);
12121 return status;
12122 }
12123
12124 hHal = pHddCtx->hHal;
12125
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012126 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12127 dbm, ccmCfgSetCallback,
12128 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012129 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012130 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012131 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12132 return -EIO;
12133 }
12134
12135 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12136 dbm);
12137
12138 switch(type)
12139 {
12140 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12141 /* Fall through */
12142 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12143 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12144 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12146 __func__);
12147 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012148 }
12149 break;
12150 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 __func__);
12153 return -EOPNOTSUPP;
12154 break;
12155 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12157 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 return -EIO;
12159 }
12160
12161 return 0;
12162}
12163
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012164static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12165#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12166 struct wireless_dev *wdev,
12167#endif
12168#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12169 enum tx_power_setting type,
12170#else
12171 enum nl80211_tx_power_setting type,
12172#endif
12173 int dbm)
12174{
12175 int ret;
12176 vos_ssr_protect(__func__);
12177 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12178#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12179 wdev,
12180#endif
12181#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12182 type,
12183#else
12184 type,
12185#endif
12186 dbm);
12187 vos_ssr_unprotect(__func__);
12188
12189 return ret;
12190}
12191
Jeff Johnson295189b2012-06-20 16:38:30 -070012192/*
12193 * FUNCTION: wlan_hdd_cfg80211_get_txpower
12194 * This function is used to read the txpower
12195 */
Yue Maf49ba872013-08-19 12:04:25 -070012196static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12197#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12198 struct wireless_dev *wdev,
12199#endif
12200 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012201{
12202
12203 hdd_adapter_t *pAdapter;
12204 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012205 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012206
Jeff Johnsone7245742012-09-05 17:12:55 -070012207 ENTER();
12208
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012209 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012210
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012211 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012212 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12214 "%s: HDD context is not valid", __func__);
12215 *dbm = 0;
12216 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012217 }
12218
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12220 if (NULL == pAdapter)
12221 {
12222 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12223 return -ENOENT;
12224 }
12225
12226 wlan_hdd_get_classAstats(pAdapter);
12227 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12228
Jeff Johnsone7245742012-09-05 17:12:55 -070012229 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012230 return 0;
12231}
12232
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012233static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 u8* mac, struct station_info *sinfo)
12235{
12236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12237 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12238 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012239 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012240
12241 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12242 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012243
12244 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12245 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12246 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12247 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12248 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12249 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12250 tANI_U16 maxRate = 0;
12251 tANI_U16 myRate;
12252 tANI_U16 currentRate = 0;
12253 tANI_U8 maxSpeedMCS = 0;
12254 tANI_U8 maxMCSIdx = 0;
12255 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012256 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012257 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012258 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012259
Leo Chang6f8870f2013-03-26 18:11:36 -070012260#ifdef WLAN_FEATURE_11AC
12261 tANI_U32 vht_mcs_map;
12262 eDataRate11ACMaxMcs vhtMaxMcs;
12263#endif /* WLAN_FEATURE_11AC */
12264
Jeff Johnsone7245742012-09-05 17:12:55 -070012265 ENTER();
12266
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12268 (0 == ssidlen))
12269 {
12270 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12271 " Invalid ssidlen, %d", __func__, ssidlen);
12272 /*To keep GUI happy*/
12273 return 0;
12274 }
12275
Mukul Sharma811205f2014-07-09 21:07:30 +053012276 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12277 {
12278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12279 "%s: Roaming in progress, so unable to proceed this request", __func__);
12280 return 0;
12281 }
12282
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012283 status = wlan_hdd_validate_context(pHddCtx);
12284
12285 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012286 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12288 "%s: HDD context is not valid", __func__);
12289 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012290 }
12291
Jeff Johnson295189b2012-06-20 16:38:30 -070012292
Kiet Lam3b17fc82013-09-27 05:24:08 +053012293 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12294 sinfo->filled |= STATION_INFO_SIGNAL;
12295
c_hpothu09f19542014-05-30 21:53:31 +053012296 wlan_hdd_get_station_stats(pAdapter);
12297 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12298
12299 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012300 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12301 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012302 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012303 {
12304 rate_flags = pAdapter->maxRateFlags;
12305 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012306
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 //convert to the UI units of 100kbps
12308 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12309
12310#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012311 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 -070012312 sinfo->signal,
12313 pCfg->reportMaxLinkSpeed,
12314 myRate,
12315 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012316 (int) pCfg->linkSpeedRssiMid,
12317 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012318 (int) rate_flags,
12319 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012320#endif //LINKSPEED_DEBUG_ENABLED
12321
12322 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12323 {
12324 // we do not want to necessarily report the current speed
12325 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12326 {
12327 // report the max possible speed
12328 rssidx = 0;
12329 }
12330 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12331 {
12332 // report the max possible speed with RSSI scaling
12333 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12334 {
12335 // report the max possible speed
12336 rssidx = 0;
12337 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012338 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012339 {
12340 // report middle speed
12341 rssidx = 1;
12342 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012343 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12344 {
12345 // report middle speed
12346 rssidx = 2;
12347 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 else
12349 {
12350 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012351 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 }
12353 }
12354 else
12355 {
12356 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12357 hddLog(VOS_TRACE_LEVEL_ERROR,
12358 "%s: Invalid value for reportMaxLinkSpeed: %u",
12359 __func__, pCfg->reportMaxLinkSpeed);
12360 rssidx = 0;
12361 }
12362
12363 maxRate = 0;
12364
12365 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012366 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12367 OperationalRates, &ORLeng))
12368 {
12369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12370 /*To keep GUI happy*/
12371 return 0;
12372 }
12373
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 for (i = 0; i < ORLeng; i++)
12375 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012376 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 {
12378 /* Validate Rate Set */
12379 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12380 {
12381 currentRate = supported_data_rate[j].supported_rate[rssidx];
12382 break;
12383 }
12384 }
12385 /* Update MAX rate */
12386 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12387 }
12388
12389 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012390 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12391 ExtendedRates, &ERLeng))
12392 {
12393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12394 /*To keep GUI happy*/
12395 return 0;
12396 }
12397
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 for (i = 0; i < ERLeng; i++)
12399 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012400 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 {
12402 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12403 {
12404 currentRate = supported_data_rate[j].supported_rate[rssidx];
12405 break;
12406 }
12407 }
12408 /* Update MAX rate */
12409 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12410 }
c_hpothu79aab322014-07-14 21:11:01 +053012411
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012412 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012413 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012414 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012415 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 {
c_hpothu79aab322014-07-14 21:11:01 +053012417 if (rate_flags & eHAL_TX_RATE_VHT80)
12418 mode = 2;
12419 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12420 mode = 1;
12421 else
12422 mode = 0;
12423
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012424 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12425 MCSRates, &MCSLeng))
12426 {
12427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12428 /*To keep GUI happy*/
12429 return 0;
12430 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012432#ifdef WLAN_FEATURE_11AC
12433 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012434 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012435 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012436 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012437 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012438 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012440 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012442 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012444 maxMCSIdx = 7;
12445 }
12446 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12447 {
12448 maxMCSIdx = 8;
12449 }
12450 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12451 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012452 //VHT20 is supporting 0~8
12453 if (rate_flags & eHAL_TX_RATE_VHT20)
12454 maxMCSIdx = 8;
12455 else
12456 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012457 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012458
c_hpothu79aab322014-07-14 21:11:01 +053012459 if (0 != rssidx)/*check for scaled */
12460 {
12461 //get middle rate MCS index if rssi=1/2
12462 for (i=0; i <= maxMCSIdx; i++)
12463 {
12464 if (sinfo->signal <= rssiMcsTbl[mode][i])
12465 {
12466 maxMCSIdx = i;
12467 break;
12468 }
12469 }
12470 }
12471
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012472 if (rate_flags & eHAL_TX_RATE_VHT80)
12473 {
12474 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12475 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12476 }
12477 else if (rate_flags & eHAL_TX_RATE_VHT40)
12478 {
12479 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12480 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12481 }
12482 else if (rate_flags & eHAL_TX_RATE_VHT20)
12483 {
12484 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12485 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12486 }
12487
Leo Chang6f8870f2013-03-26 18:11:36 -070012488 maxSpeedMCS = 1;
12489 if (currentRate > maxRate)
12490 {
12491 maxRate = currentRate;
12492 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012493
Leo Chang6f8870f2013-03-26 18:11:36 -070012494 }
12495 else
12496#endif /* WLAN_FEATURE_11AC */
12497 {
12498 if (rate_flags & eHAL_TX_RATE_HT40)
12499 {
12500 rateFlag |= 1;
12501 }
12502 if (rate_flags & eHAL_TX_RATE_SGI)
12503 {
12504 rateFlag |= 2;
12505 }
12506
Girish Gowli01abcee2014-07-31 20:18:55 +053012507 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012508 if (rssidx == 1 || rssidx == 2)
12509 {
12510 //get middle rate MCS index if rssi=1/2
12511 for (i=0; i <= 7; i++)
12512 {
12513 if (sinfo->signal <= rssiMcsTbl[mode][i])
12514 {
12515 temp = i+1;
12516 break;
12517 }
12518 }
12519 }
c_hpothu79aab322014-07-14 21:11:01 +053012520
12521 for (i = 0; i < MCSLeng; i++)
12522 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012523 for (j = 0; j < temp; j++)
12524 {
12525 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12526 {
12527 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12528 break;
12529 }
12530 }
12531 if ((j < temp) && (currentRate > maxRate))
12532 {
12533 maxRate = currentRate;
12534 maxSpeedMCS = 1;
12535 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 }
12538 }
12539 }
12540
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012541 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12542 {
12543 maxRate = myRate;
12544 maxSpeedMCS = 1;
12545 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12546 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012547 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012548 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 {
12550 maxRate = myRate;
12551 if (rate_flags & eHAL_TX_RATE_LEGACY)
12552 {
12553 maxSpeedMCS = 0;
12554 }
12555 else
12556 {
12557 maxSpeedMCS = 1;
12558 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12559 }
12560 }
12561
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012562 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 {
12564 sinfo->txrate.legacy = maxRate;
12565#ifdef LINKSPEED_DEBUG_ENABLED
12566 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12567#endif //LINKSPEED_DEBUG_ENABLED
12568 }
12569 else
12570 {
12571 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012572#ifdef WLAN_FEATURE_11AC
12573 sinfo->txrate.nss = 1;
12574 if (rate_flags & eHAL_TX_RATE_VHT80)
12575 {
12576 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012577 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012578 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012579 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012580 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012581 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12582 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12583 }
12584 else if (rate_flags & eHAL_TX_RATE_VHT20)
12585 {
12586 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12587 }
12588#endif /* WLAN_FEATURE_11AC */
12589 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12590 {
12591 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12592 if (rate_flags & eHAL_TX_RATE_HT40)
12593 {
12594 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12595 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 if (rate_flags & eHAL_TX_RATE_SGI)
12598 {
12599 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12600 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012601
Jeff Johnson295189b2012-06-20 16:38:30 -070012602#ifdef LINKSPEED_DEBUG_ENABLED
12603 pr_info("Reporting MCS rate %d flags %x\n",
12604 sinfo->txrate.mcs,
12605 sinfo->txrate.flags );
12606#endif //LINKSPEED_DEBUG_ENABLED
12607 }
12608 }
12609 else
12610 {
12611 // report current rate instead of max rate
12612
12613 if (rate_flags & eHAL_TX_RATE_LEGACY)
12614 {
12615 //provide to the UI in units of 100kbps
12616 sinfo->txrate.legacy = myRate;
12617#ifdef LINKSPEED_DEBUG_ENABLED
12618 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12619#endif //LINKSPEED_DEBUG_ENABLED
12620 }
12621 else
12622 {
12623 //must be MCS
12624 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012625#ifdef WLAN_FEATURE_11AC
12626 sinfo->txrate.nss = 1;
12627 if (rate_flags & eHAL_TX_RATE_VHT80)
12628 {
12629 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12630 }
12631 else
12632#endif /* WLAN_FEATURE_11AC */
12633 {
12634 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 if (rate_flags & eHAL_TX_RATE_SGI)
12637 {
12638 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12639 }
12640 if (rate_flags & eHAL_TX_RATE_HT40)
12641 {
12642 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12643 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012644#ifdef WLAN_FEATURE_11AC
12645 else if (rate_flags & eHAL_TX_RATE_VHT80)
12646 {
12647 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12648 }
12649#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012650#ifdef LINKSPEED_DEBUG_ENABLED
12651 pr_info("Reporting actual MCS rate %d flags %x\n",
12652 sinfo->txrate.mcs,
12653 sinfo->txrate.flags );
12654#endif //LINKSPEED_DEBUG_ENABLED
12655 }
12656 }
12657 sinfo->filled |= STATION_INFO_TX_BITRATE;
12658
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012659 sinfo->tx_packets =
12660 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12661 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12662 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12663 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12664
12665 sinfo->tx_retries =
12666 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12667 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12668 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12669 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12670
12671 sinfo->tx_failed =
12672 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12673 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12674 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12675 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12676
12677 sinfo->filled |=
12678 STATION_INFO_TX_PACKETS |
12679 STATION_INFO_TX_RETRIES |
12680 STATION_INFO_TX_FAILED;
12681
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12683 TRACE_CODE_HDD_CFG80211_GET_STA,
12684 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012685 EXIT();
12686 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012687}
12688
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012689static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12690 u8* mac, struct station_info *sinfo)
12691{
12692 int ret;
12693
12694 vos_ssr_protect(__func__);
12695 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12696 vos_ssr_unprotect(__func__);
12697
12698 return ret;
12699}
12700
12701static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012702 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012703{
12704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012705 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012707 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012708
Jeff Johnsone7245742012-09-05 17:12:55 -070012709 ENTER();
12710
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 if (NULL == pAdapter)
12712 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012713 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 return -ENODEV;
12715 }
12716
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012717 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12718 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12719 pAdapter->sessionId, timeout));
12720
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012721 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012722 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012723
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012724 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012725 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12727 "%s: HDD context is not valid", __func__);
12728 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012729 }
12730
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012731 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12732 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12733 (pHddCtx->cfg_ini->fhostArpOffload) &&
12734 (eConnectionState_Associated ==
12735 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12736 {
Amar Singhald53568e2013-09-26 11:03:45 -070012737
12738 hddLog(VOS_TRACE_LEVEL_INFO,
12739 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012740 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012741 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12742 {
12743 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012744 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012745 __func__, vos_status);
12746 }
12747 }
12748
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 /**The get power cmd from the supplicant gets updated by the nl only
12750 *on successful execution of the function call
12751 *we are oppositely mapped w.r.t mode in the driver
12752 **/
12753 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12754
Jeff Johnsone7245742012-09-05 17:12:55 -070012755 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012756 if (VOS_STATUS_E_FAILURE == vos_status)
12757 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12759 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012760 return -EINVAL;
12761 }
12762 return 0;
12763}
12764
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012765static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12766 struct net_device *dev, bool mode, int timeout)
12767{
12768 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012769
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012770 vos_ssr_protect(__func__);
12771 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12772 vos_ssr_unprotect(__func__);
12773
12774 return ret;
12775}
Jeff Johnson295189b2012-06-20 16:38:30 -070012776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12777static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12778 struct net_device *netdev,
12779 u8 key_index)
12780{
Jeff Johnsone7245742012-09-05 17:12:55 -070012781 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 return 0;
12783}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012784#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070012785
12786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12787static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12788 struct net_device *dev,
12789 struct ieee80211_txq_params *params)
12790{
Jeff Johnsone7245742012-09-05 17:12:55 -070012791 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 return 0;
12793}
12794#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12795static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
12796 struct ieee80211_txq_params *params)
12797{
Jeff Johnsone7245742012-09-05 17:12:55 -070012798 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 return 0;
12800}
12801#endif //LINUX_VERSION_CODE
12802
Naresh Jayaram60c03102014-10-14 12:29:12 +053012803static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012804 struct net_device *dev,
12805 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012806{
12807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012808 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012809 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012810 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012811 v_U8_t staId;
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012812 v_CONTEXT_t pVosContext = NULL;
12813 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012814 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012815
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012816 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070012817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 return -EINVAL;
12820 }
12821
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012822 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12823 TRACE_CODE_HDD_CFG80211_DEL_STA,
12824 pAdapter->sessionId, pAdapter->device_mode));
12825
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12827 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012828
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012829 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012830 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12832 "%s: HDD context is not valid", __func__);
12833 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012834 }
12835
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012837 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 )
12839 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012840 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12841 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12842 if(pSapCtx == NULL){
12843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12844 FL("psapCtx is NULL"));
12845 return -ENOENT;
12846 }
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012847 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 {
12849 v_U16_t i;
12850 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12851 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012852 if ((pSapCtx->aStaInfo[i].isUsed) &&
12853 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 {
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012855 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012856 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012857 ETHER_ADDR_LEN);
12858
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012860 "%s: Delete STA with MAC::"
12861 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012862 __func__,
12863 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
12864 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012865 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012866 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012867 }
12868 }
12869 }
12870 else
12871 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012872
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012873 vos_status = hdd_softap_GetStaId(pAdapter,
12874 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012875 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12876 {
12877 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012878 "%s: Skip this DEL STA as this is not used::"
12879 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012880 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012881 return -ENOENT;
12882 }
12883
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012884 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012885 {
12886 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080012887 "%s: Skip this DEL STA as deauth is in progress::"
12888 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012889 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012890 return -ENOENT;
12891 }
12892
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012893 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012894
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 hddLog(VOS_TRACE_LEVEL_INFO,
12896 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012897 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 __func__,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012899 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012900
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012901 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012902 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12903 {
Sachin Ahujaa9cf1e52014-11-07 13:01:24 +053012904 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012905 hddLog(VOS_TRACE_LEVEL_INFO,
12906 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080012907 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012908 __func__,
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012909 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012910 return -ENOENT;
12911 }
12912
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 }
12914 }
12915
12916 EXIT();
12917
12918 return 0;
12919}
Naresh Jayaram60c03102014-10-14 12:29:12 +053012920
12921#ifdef CFG80211_DEL_STA_V2
12922static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12923 struct net_device *dev,
12924 struct station_del_parameters *param)
12925#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012926static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
12927 struct net_device *dev, u8 *mac)
Naresh Jayaram60c03102014-10-14 12:29:12 +053012928#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012929{
12930 int ret;
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012931 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070012932
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012933 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012934
Naresh Jayaram60c03102014-10-14 12:29:12 +053012935#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012936 if (NULL == param) {
12937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
12938 return -EINVAL;
12939 }
12940
12941 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
12942 param->subtype, &delStaParams);
12943
Naresh Jayaram60c03102014-10-14 12:29:12 +053012944#else
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012945 WLANSAP_PopulateDelStaParams(mac, eCsrForcedDeauthSta,
12946 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram60c03102014-10-14 12:29:12 +053012947#endif
Hanumantha Reddy Pothulaec47b8f2014-10-31 14:03:37 +053012948 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
12949
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012950 vos_ssr_unprotect(__func__);
12951
12952 return ret;
12953}
12954
12955static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012956 struct net_device *dev, u8 *mac, struct station_parameters *params)
12957{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012959 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012960#ifdef FEATURE_WLAN_TDLS
12961 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012962 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012963
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012964 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12965 TRACE_CODE_HDD_CFG80211_ADD_STA,
12966 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012967 mask = params->sta_flags_mask;
12968
12969 set = params->sta_flags_set;
12970
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012971#ifdef WLAN_FEATURE_TDLS_DEBUG
12972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12973 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
12974 __func__, mask, set, MAC_ADDR_ARRAY(mac));
12975#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012976
12977 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12978 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012979 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012980 }
12981 }
12982#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012983 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012984}
12985
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012986static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
12987 struct net_device *dev, u8 *mac, struct station_parameters *params)
12988{
12989 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012990
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012991 vos_ssr_protect(__func__);
12992 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
12993 vos_ssr_unprotect(__func__);
12994
12995 return ret;
12996}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012997#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070012998
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012999static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013000 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013001{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13003 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013004 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013005 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013006 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013007 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013008
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013009 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013010 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013011 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013013 return -EINVAL;
13014 }
13015
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013016 if (!pmksa) {
13017 hddLog(LOGE, FL("pmksa is NULL"));
13018 return -EINVAL;
13019 }
13020
13021 if (!pmksa->bssid || !pmksa->pmkid) {
13022 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13023 pmksa->bssid, pmksa->pmkid);
13024 return -EINVAL;
13025 }
13026
13027 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13028 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013030 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13031 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013032
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013033 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13036 "%s: HDD context is not valid", __func__);
13037 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013038 }
13039
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013041 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13042
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013043 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13044 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013045
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013046 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013047 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013048 &pmk_id, 1, FALSE);
13049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13051 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13052 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013053
13054 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013055}
13056
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013057static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13058 struct cfg80211_pmksa *pmksa)
13059{
13060 int ret;
13061
13062 vos_ssr_protect(__func__);
13063 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13064 vos_ssr_unprotect(__func__);
13065
13066 return ret;
13067}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013068
Wilson Yang6507c4e2013-10-01 20:11:19 -070013069
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013070static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013071 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013072{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13074 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013075 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013076 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013077
Wilson Yang6507c4e2013-10-01 20:11:19 -070013078 /* Validate pAdapter */
13079 if (NULL == pAdapter)
13080 {
13081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13082 return -EINVAL;
13083 }
13084
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013085 if (!pmksa) {
13086 hddLog(LOGE, FL("pmksa is NULL"));
13087 return -EINVAL;
13088 }
13089
13090 if (!pmksa->bssid) {
13091 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13092 return -EINVAL;
13093 }
13094
Kiet Lam85680f32014-10-31 15:34:57 -070013095 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13096 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13097
Wilson Yang6507c4e2013-10-01 20:11:19 -070013098 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13099 status = wlan_hdd_validate_context(pHddCtx);
13100
13101 if (0 != status)
13102 {
13103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13104 "%s: HDD context is not valid", __func__);
13105 return status;
13106 }
13107
13108 /*Retrieve halHandle*/
13109 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13110
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013111 /* Delete the PMKID CSR cache */
13112 if (eHAL_STATUS_SUCCESS !=
13113 sme_RoamDelPMKIDfromCache(halHandle,
13114 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13115 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13116 MAC_ADDR_ARRAY(pmksa->bssid));
13117 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013118 }
13119
Wilson Yangef657d32014-01-15 19:19:23 -080013120 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013121}
13122
Wilson Yang6507c4e2013-10-01 20:11:19 -070013123
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013124static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13125 struct cfg80211_pmksa *pmksa)
13126{
13127 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013128
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013129 vos_ssr_protect(__func__);
13130 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13131 vos_ssr_unprotect(__func__);
13132
13133 return ret;
13134
13135}
13136
13137static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013138{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13140 tHalHandle halHandle;
13141 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013142 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013143
13144 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13145
13146 /* Validate pAdapter */
13147 if (NULL == pAdapter)
13148 {
13149 hddLog(VOS_TRACE_LEVEL_ERROR,
13150 "%s: Invalid Adapter" ,__func__);
13151 return -EINVAL;
13152 }
13153
13154 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13155 status = wlan_hdd_validate_context(pHddCtx);
13156
13157 if (0 != status)
13158 {
13159 hddLog(VOS_TRACE_LEVEL_ERROR,
13160 "%s: HDD context is not valid", __func__);
13161 return status;
13162 }
13163
13164 /*Retrieve halHandle*/
13165 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13166
Kanchanapally, Vidyullatha93d556a2014-09-25 15:16:50 +053013167 /* Flush the PMKID cache in CSR */
13168 if (eHAL_STATUS_SUCCESS !=
13169 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13171 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013172 }
13173
Wilson Yangef657d32014-01-15 19:19:23 -080013174 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013175}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013176
13177static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13178{
13179 int ret;
13180
13181 vos_ssr_protect(__func__);
13182 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13183 vos_ssr_unprotect(__func__);
13184
13185 return ret;
13186}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013187#endif
13188
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013189#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013190static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13191 struct net_device *dev,
13192 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013193{
13194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13195 hdd_station_ctx_t *pHddStaCtx;
13196
13197 if (NULL == pAdapter)
13198 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013200 return -ENODEV;
13201 }
13202
13203 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13204
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013205 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13206 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13207 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013208 // Added for debug on reception of Re-assoc Req.
13209 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13210 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013211 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013212 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013213 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013214 }
13215
13216#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013217 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013218 ftie->ie_len);
13219#endif
13220
13221 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013222 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13223 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013224 ftie->ie_len);
13225 return 0;
13226}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013227
13228static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13229 struct net_device *dev,
13230 struct cfg80211_update_ft_ies_params *ftie)
13231{
13232 int ret;
13233
13234 vos_ssr_protect(__func__);
13235 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13236 vos_ssr_unprotect(__func__);
13237
13238 return ret;
13239}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013240#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013241
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013242#ifdef FEATURE_WLAN_SCAN_PNO
13243
13244void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13245 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13246{
13247 int ret;
13248 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13249 hdd_context_t *pHddCtx;
13250
Nirav Shah80830bf2013-12-31 16:35:12 +053013251 ENTER();
13252
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013253 if (NULL == pAdapter)
13254 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013256 "%s: HDD adapter is Null", __func__);
13257 return ;
13258 }
13259
13260 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13261 if (NULL == pHddCtx)
13262 {
13263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13264 "%s: HDD context is Null!!!", __func__);
13265 return ;
13266 }
13267
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013268 spin_lock(&pHddCtx->schedScan_lock);
13269 if (TRUE == pHddCtx->isWiphySuspended)
13270 {
13271 pHddCtx->isSchedScanUpdatePending = TRUE;
13272 spin_unlock(&pHddCtx->schedScan_lock);
13273 hddLog(VOS_TRACE_LEVEL_INFO,
13274 "%s: Update cfg80211 scan database after it resume", __func__);
13275 return ;
13276 }
13277 spin_unlock(&pHddCtx->schedScan_lock);
13278
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013279 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13280
13281 if (0 > ret)
13282 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13283
13284 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13286 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013287}
13288
13289/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013290 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013291 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013292 */
13293static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13294{
13295 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13296 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013297 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013298 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13299 int status = 0;
13300 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13301
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013302 /* The current firmware design does not allow PNO during any
13303 * active sessions. Hence, determine the active sessions
13304 * and return a failure.
13305 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013306 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13307 {
13308 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013309 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013310
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013311 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13312 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13313 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13314 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13315 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhaled9b2a12014-11-07 14:31:56 +053013316 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013317 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013318 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013319 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013320 }
13321 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13322 pAdapterNode = pNext;
13323 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013324 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013325}
13326
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013327void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13328{
13329 hdd_adapter_t *pAdapter = callbackContext;
13330 hdd_context_t *pHddCtx;
13331
13332 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13333 {
13334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13335 FL("Invalid adapter or adapter has invalid magic"));
13336 return;
13337 }
13338
13339 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13340 if (0 != wlan_hdd_validate_context(pHddCtx))
13341 {
13342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13343 FL("HDD context is not valid"));
13344 return;
13345 }
13346
c_hpothub53c45d2014-08-18 16:53:14 +053013347 if (VOS_STATUS_SUCCESS != status)
13348 {
13349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013350 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013351 pHddCtx->isPnoEnable = FALSE;
13352 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013353
13354 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13355 complete(&pAdapter->pno_comp_var);
13356}
13357
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013358/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013359 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13360 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013361 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013362static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013363 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13364{
13365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
c_hpothuebdb0aa2015-02-24 14:09:09 +053013366 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013367 hdd_context_t *pHddCtx;
13368 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013369 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013370 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13371 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013372 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13373 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013374 int ret = 0;
Sachin Ahuja4c5aa762014-11-12 18:57:11 +053013375 hdd_config_t *pConfig = NULL;
13376 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013377
13378 if (NULL == pAdapter)
13379 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013381 "%s: HDD adapter is Null", __func__);
13382 return -ENODEV;
13383 }
13384
13385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013386 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013387
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013388 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013389 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13391 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013392 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013393 }
13394
Sachin Ahuja4c5aa762014-11-12 18:57:11 +053013395 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013396 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13397 if (NULL == hHal)
13398 {
13399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13400 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013401 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013402 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013403 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013404 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013405 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013406 {
13407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13408 "%s: aborting the existing scan is unsuccessfull", __func__);
13409 return -EBUSY;
13410 }
13411
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013412 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013413 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013415 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013416 return -EBUSY;
13417 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013418
c_hpothu37f21312014-04-09 21:49:54 +053013419 if (TRUE == pHddCtx->isPnoEnable)
13420 {
13421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13422 FL("already PNO is enabled"));
13423 return -EBUSY;
13424 }
c_hpothu3599e4e2014-10-22 17:45:13 +053013425
13426 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13427 {
13428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13429 "%s: abort ROC failed ", __func__);
13430 return -EBUSY;
13431 }
13432
c_hpothu37f21312014-04-09 21:49:54 +053013433 pHddCtx->isPnoEnable = TRUE;
13434
c_hpothuebdb0aa2015-02-24 14:09:09 +053013435 pnoRequest.enable = 1; /*Enable PNO */
13436 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013437
c_hpothuebdb0aa2015-02-24 14:09:09 +053013438 if (( !pnoRequest.ucNetworksCount ) ||
13439 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013440 {
13441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013442 "%s: Network input is not correct %d Max Network supported is %d",
c_hpothuebdb0aa2015-02-24 14:09:09 +053013443 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013444 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013445 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013446 goto error;
13447 }
13448
13449 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13450 {
13451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013452 "%s: Incorrect number of channels %d",
13453 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013454 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013455 goto error;
13456 }
13457
13458 /* Framework provides one set of channels(all)
13459 * common for all saved profile */
13460 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13461 channels_allowed, &num_channels_allowed))
13462 {
13463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13464 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013465 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013466 goto error;
13467 }
13468 /* Checking each channel against allowed channel list */
13469 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013470 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013471 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013472 char chList [(request->n_channels*5)+1];
13473 int len;
13474 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013475 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013476 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013477 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013478 if (request->channels[i]->hw_value == channels_allowed[indx])
13479 {
Sachin Ahuja4c5aa762014-11-12 18:57:11 +053013480 if ((!pConfig->enableDFSPnoChnlScan) &&
13481 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13482 {
13483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13484 "%s : Dropping DFS channel : %d",
13485 __func__,channels_allowed[indx]);
13486 num_ignore_dfs_ch++;
13487 break;
13488 }
13489
Nirav Shah80830bf2013-12-31 16:35:12 +053013490 valid_ch[num_ch++] = request->channels[i]->hw_value;
13491 len += snprintf(chList+len, 5, "%d ",
13492 request->channels[i]->hw_value);
13493 break ;
13494 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013495 }
13496 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013497 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013498
Sachin Ahuja4c5aa762014-11-12 18:57:11 +053013499 /*If all channels are DFS and dropped, then ignore the PNO request*/
13500 if (num_ignore_dfs_ch == request->n_channels)
13501 {
13502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13503 "%s : All requested channels are DFS channels", __func__);
13504 ret = -EINVAL;
13505 goto error;
13506 }
13507 }
c_hpothuebdb0aa2015-02-24 14:09:09 +053013508
13509 pnoRequest.aNetworks =
13510 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
13511 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013512 {
c_hpothuebdb0aa2015-02-24 14:09:09 +053013513 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
13514 FL("failed to allocate memory aNetworks %u"),
13515 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
13516 goto error;
13517 }
13518 vos_mem_zero(pnoRequest.aNetworks,
13519 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
13520
13521 /* Filling per profile params */
13522 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
13523 {
13524 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013525 request->match_sets[i].ssid.ssid_len;
13526
c_hpothuebdb0aa2015-02-24 14:09:09 +053013527 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
13528 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013529 {
13530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013531 "%s: SSID Len %d is not correct for network %d",
c_hpothuebdb0aa2015-02-24 14:09:09 +053013532 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013533 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013534 goto error;
13535 }
13536
c_hpothuebdb0aa2015-02-24 14:09:09 +053013537 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013538 request->match_sets[i].ssid.ssid,
13539 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13541 "%s: SSID of network %d is %s ", __func__,
c_hpothuebdb0aa2015-02-24 14:09:09 +053013542 i, pnoRequest.aNetworks[i].ssId.ssId);
13543 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13544 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
13545 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013546
13547 /*Copying list of valid channel into request */
c_hpothuebdb0aa2015-02-24 14:09:09 +053013548 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
13549 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013550
c_hpothuebdb0aa2015-02-24 14:09:09 +053013551 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013552 }
13553
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013554 for (i = 0; i < request->n_ssids; i++)
13555 {
13556 j = 0;
c_hpothuebdb0aa2015-02-24 14:09:09 +053013557 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013558 {
c_hpothuebdb0aa2015-02-24 14:09:09 +053013559 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013560 request->ssids[i].ssid_len) &&
c_hpothuebdb0aa2015-02-24 14:09:09 +053013561 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013562 request->ssids[i].ssid,
c_hpothuebdb0aa2015-02-24 14:09:09 +053013563 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013564 {
c_hpothuebdb0aa2015-02-24 14:09:09 +053013565 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013566 break;
13567 }
13568 j++;
13569 }
13570 }
13571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13572 "Number of hidden networks being Configured = %d",
13573 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013575 "request->ie_len = %zu", request->ie_len);
c_hpothuebdb0aa2015-02-24 14:09:09 +053013576
13577 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
13578 if (pnoRequest.p24GProbeTemplate == NULL)
13579 {
13580 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
13581 FL("failed to allocate memory p24GProbeTemplate %u"),
13582 SIR_PNO_MAX_PB_REQ_SIZE);
13583 goto error;
13584 }
13585
13586 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
13587 if (pnoRequest.p5GProbeTemplate == NULL)
13588 {
13589 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
13590 FL("failed to allocate memory p5GProbeTemplate %u"),
13591 SIR_PNO_MAX_PB_REQ_SIZE);
13592 goto error;
13593 }
13594
13595 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
13596 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
13597
Hanumantha Reddy Pothula846cf712015-03-03 18:31:39 +053013598 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
13599 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013600 {
c_hpothuebdb0aa2015-02-24 14:09:09 +053013601 pnoRequest.us24GProbeTemplateLen = request->ie_len;
13602 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
13603 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013604
c_hpothuebdb0aa2015-02-24 14:09:09 +053013605 pnoRequest.us5GProbeTemplateLen = request->ie_len;
13606 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
13607 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013608 }
13609
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013610 /* Driver gets only one time interval which is hardcoded in
13611 * supplicant for 10000ms. Taking power consumption into account 6 timers
13612 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13613 * 80,160,320 secs. And number of scan cycle for each timer
13614 * is configurable through INI param gPNOScanTimerRepeatValue.
13615 * If it is set to 0 only one timer will be used and PNO scan cycle
13616 * will be repeated after each interval specified by supplicant
13617 * till PNO is disabled.
13618 */
13619 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
c_hpothuebdb0aa2015-02-24 14:09:09 +053013620 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013621 else
c_hpothuebdb0aa2015-02-24 14:09:09 +053013622 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013623 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13624
13625 tempInterval = (request->interval)/1000;
13626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13627 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13628 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
c_hpothuebdb0aa2015-02-24 14:09:09 +053013629 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013630 {
c_hpothuebdb0aa2015-02-24 14:09:09 +053013631 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013632 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
c_hpothuebdb0aa2015-02-24 14:09:09 +053013633 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013634 tempInterval *= 2;
13635 }
13636 //Repeat last timer until pno disabled.
c_hpothuebdb0aa2015-02-24 14:09:09 +053013637 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013638
c_hpothuebdb0aa2015-02-24 14:09:09 +053013639 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013640
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013641 INIT_COMPLETION(pAdapter->pno_comp_var);
c_hpothuebdb0aa2015-02-24 14:09:09 +053013642 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13643 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013644 pAdapter->pno_req_status = 0;
13645
Nirav Shah80830bf2013-12-31 16:35:12 +053013646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13647 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
c_hpothuebdb0aa2015-02-24 14:09:09 +053013648 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
13649 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053013650
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013651 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
c_hpothuebdb0aa2015-02-24 14:09:09 +053013652 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013653 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13654 if (eHAL_STATUS_SUCCESS != status)
13655 {
13656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013657 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013658 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013659 goto error;
13660 }
13661
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013662 ret = wait_for_completion_timeout(
13663 &pAdapter->pno_comp_var,
13664 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13665 if (0 >= ret)
13666 {
13667 // Did not receive the response for PNO enable in time.
13668 // Assuming the PNO enable was success.
13669 // Returning error from here, because we timeout, results
13670 // in side effect of Wifi (Wifi Setting) not to work.
13671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13672 FL("Timed out waiting for PNO to be Enabled"));
13673 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013674 }
13675
13676 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013677 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013678
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013679error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13681 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053013682 pHddCtx->isPnoEnable = FALSE;
c_hpothuebdb0aa2015-02-24 14:09:09 +053013683 if (pnoRequest.aNetworks)
13684 vos_mem_free(pnoRequest.aNetworks);
13685 if (pnoRequest.p24GProbeTemplate)
13686 vos_mem_free(pnoRequest.p24GProbeTemplate);
13687 if (pnoRequest.p5GProbeTemplate)
13688 vos_mem_free(pnoRequest.p5GProbeTemplate);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013689 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013690}
13691
13692/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013693 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13694 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013695 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013696static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13697 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13698{
13699 int ret;
13700
13701 vos_ssr_protect(__func__);
13702 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13703 vos_ssr_unprotect(__func__);
13704
13705 return ret;
13706}
13707
13708/*
13709 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13710 * Function to disable PNO
13711 */
13712static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013713 struct net_device *dev)
13714{
13715 eHalStatus status = eHAL_STATUS_FAILURE;
13716 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13717 hdd_context_t *pHddCtx;
13718 tHalHandle hHal;
c_hpothuebdb0aa2015-02-24 14:09:09 +053013719 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013720 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013721
13722 ENTER();
13723
13724 if (NULL == pAdapter)
13725 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013727 "%s: HDD adapter is Null", __func__);
13728 return -ENODEV;
13729 }
13730
13731 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013732
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013733 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013734 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013736 "%s: HDD context is Null", __func__);
13737 return -ENODEV;
13738 }
13739
13740 /* The return 0 is intentional when isLogpInProgress and
13741 * isLoadUnloadInProgress. We did observe a crash due to a return of
13742 * failure in sched_scan_stop , especially for a case where the unload
13743 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13744 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13745 * success. If it returns a failure , then its next invocation due to the
13746 * clean up of the second interface will have the dev pointer corresponding
13747 * to the first one leading to a crash.
13748 */
13749 if (pHddCtx->isLogpInProgress)
13750 {
13751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13752 "%s: LOGP in Progress. Ignore!!!", __func__);
13753 return ret;
13754 }
13755
Mihir Shete18156292014-03-11 15:38:30 +053013756 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013757 {
13758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13759 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13760 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013761 }
13762
13763 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13764 if (NULL == hHal)
13765 {
13766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13767 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013768 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013769 }
13770
c_hpothuebdb0aa2015-02-24 14:09:09 +053013771 pnoRequest.enable = 0; /* Disable PNO */
13772 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013773
c_hpothuebdb0aa2015-02-24 14:09:09 +053013774 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013775 pAdapter->sessionId,
13776 NULL, pAdapter);
13777 if (eHAL_STATUS_SUCCESS != status)
13778 {
13779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13780 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013781 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013782 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013783 }
c_hpothu37f21312014-04-09 21:49:54 +053013784 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013785
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013786error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013788 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013789
13790 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013791 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013792}
13793
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013794/*
13795 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
13796 * NL interface to disable PNO
13797 */
13798static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
13799 struct net_device *dev)
13800{
13801 int ret;
13802
13803 vos_ssr_protect(__func__);
13804 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
13805 vos_ssr_unprotect(__func__);
13806
13807 return ret;
13808}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013809#endif /*FEATURE_WLAN_SCAN_PNO*/
13810
13811
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013812#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013813#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013814static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13815 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013816 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
13817#else
13818static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
13819 u8 *peer, u8 action_code, u8 dialog_token,
13820 u16 status_code, const u8 *buf, size_t len)
13821#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013822{
13823
13824 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13825 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013826 u8 peerMac[6];
13827 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013828 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080013829 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070013830 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013831#if !(TDLS_MGMT_VERSION2)
13832 u32 peer_capability = 0;
13833#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013834 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13837 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
13838 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013839 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013840 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013842 "Invalid arguments");
13843 return -EINVAL;
13844 }
13845
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013846 if (pHddCtx->isLogpInProgress)
13847 {
13848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13849 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053013850 wlan_hdd_tdls_set_link_status(pAdapter,
13851 peer,
13852 eTDLS_LINK_IDLE,
13853 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080013854 return -EBUSY;
13855 }
13856
Hoonki Lee27511902013-03-14 18:19:06 -070013857 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013858 {
Hoonki Lee27511902013-03-14 18:19:06 -070013859 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13860 "%s: TDLS mode is disabled OR not enabled in FW."
13861 MAC_ADDRESS_STR " action %d declined.",
13862 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013863 return -ENOTSUPP;
13864 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013865
Hoonki Lee27511902013-03-14 18:19:06 -070013866 /* other than teardown frame, other mgmt frames are not sent if disabled */
13867 if (SIR_MAC_TDLS_TEARDOWN != action_code)
13868 {
13869 /* if tdls_mode is disabled to respond to peer's request */
13870 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
13871 {
13872 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
13873 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013874 " TDLS mode is disabled. action %d declined.",
13875 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070013876
13877 return -ENOTSUPP;
13878 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013879
13880 if (vos_max_concurrent_connections_reached())
13881 {
13882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13883 return -EINVAL;
13884 }
Hoonki Lee27511902013-03-14 18:19:06 -070013885 }
13886
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013887 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
13888 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013889 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013890 {
13891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013892 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013893 " TDLS setup is ongoing. action %d declined.",
13894 __func__, MAC_ADDR_ARRAY(peer), action_code);
13895 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013896 }
13897 }
13898
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013899 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
13900 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080013901 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013902 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
13903 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013904 {
13905 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
13906 we return error code at 'add_station()'. Hence we have this
13907 check again in addtion to add_station().
13908 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013909 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080013910 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13912 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013913 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
13914 __func__, MAC_ADDR_ARRAY(peer), action_code,
13915 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053013916 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080013917 }
13918 else
13919 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013920 /* maximum reached. tweak to send error code to peer and return
13921 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013922 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13924 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053013925 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
13926 __func__, MAC_ADDR_ARRAY(peer), status_code,
13927 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013928 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013929 /* fall through to send setup resp with failure status
13930 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080013931 }
13932 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013933 else
13934 {
13935 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013936 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013937 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013938 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013940 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
13941 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013942 return -EPERM;
13943 }
13944 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013945 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013946 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013947
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013948#ifdef WLAN_FEATURE_TDLS_DEBUG
13949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013950 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013951 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
13952 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080013953#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013954
Hoonki Leea34dd892013-02-05 22:56:02 -080013955 /*Except teardown responder will not be used so just make 0*/
13956 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013957 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080013958 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013959
13960 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013961 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013962
13963 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
13964 responder = pTdlsPeer->is_responder;
13965 else
Hoonki Leea34dd892013-02-05 22:56:02 -080013966 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053013968 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070013969 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
13970 dialog_token, status_code, len);
13971 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080013972 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013973 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013974
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013975 /* For explicit trigger of DIS_REQ come out of BMPS for
13976 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070013977 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013978 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
13979 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070013980 {
13981 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
13982 {
13983 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013984 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070013985 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
13986 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053013987 if (SIR_MAC_TDLS_DIS_REQ != action_code)
13988 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070013989 }
13990
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013991 /* make sure doesn't call send_mgmt() while it is pending */
13992 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
13993 {
13994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013995 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013996 __func__, MAC_ADDR_ARRAY(peer), action_code);
13997 return -EBUSY;
13998 }
13999
14000 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014001 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14002
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014003 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014004 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014005
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014006 if (VOS_STATUS_SUCCESS != status)
14007 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14009 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014010 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070014011 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014012 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014013 }
14014
Hoonki Leed37cbb32013-04-20 00:31:14 -070014015 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14016 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14017
14018 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014019 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014021 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014022 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014023 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014024
14025 if (pHddCtx->isLogpInProgress)
14026 {
14027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14028 "%s: LOGP in Progress. Ignore!!!", __func__);
14029 return -EAGAIN;
14030 }
14031
Hoonki Leed37cbb32013-04-20 00:31:14 -070014032 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014033 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014034 }
14035
Gopichand Nakkala05922802013-03-14 12:23:19 -070014036 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014037 {
14038 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014039 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014040 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014041
Hoonki Leea34dd892013-02-05 22:56:02 -080014042 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14043 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014044 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014045 }
14046 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14047 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014048 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014049 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014050
14051 return 0;
14052}
14053
Atul Mittal115287b2014-07-08 13:26:33 +053014054
14055int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14056 u8 *peer,
14057 cfg80211_exttdls_callback callback)
14058{
14059
14060 hddTdlsPeer_t *pTdlsPeer;
14061 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14063 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14064 __func__, MAC_ADDR_ARRAY(peer));
14065
14066 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14067 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14068
14069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14070 " %s TDLS External control and Implicit Trigger not enabled ",
14071 __func__);
14072 return -ENOTSUPP;
14073 }
14074
14075 /* To cater the requirement of establishing the TDLS link
14076 * irrespective of the data traffic , get an entry of TDLS peer.
14077 */
14078 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14079 if (pTdlsPeer == NULL) {
14080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14081 "%s: peer " MAC_ADDRESS_STR " not existing",
14082 __func__, MAC_ADDR_ARRAY(peer));
14083 return -EINVAL;
14084 }
14085
14086 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14087
14088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14089 " %s TDLS Add Force Peer Failed",
14090 __func__);
14091 return -EINVAL;
14092 }
14093 /*EXT TDLS*/
14094
14095 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14097 " %s TDLS set callback Failed",
14098 __func__);
14099 return -EINVAL;
14100 }
14101
14102 return(0);
14103
14104}
14105
14106int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14107{
14108
14109 hddTdlsPeer_t *pTdlsPeer;
14110 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14112 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14113 __func__, MAC_ADDR_ARRAY(peer));
14114
14115 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14116 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14117
14118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14119 " %s TDLS External control and Implicit Trigger not enabled ",
14120 __func__);
14121 return -ENOTSUPP;
14122 }
14123
14124
14125 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14126
14127 if ( NULL == pTdlsPeer ) {
14128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14129 " peer not exsting",
14130 __func__, MAC_ADDR_ARRAY(peer));
14131 return -EINVAL;
14132 }
14133 else {
14134 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14135 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
14136 }
14137
14138 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14139 return -EINVAL;
14140
14141 /*EXT TDLS*/
14142
14143 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14144
14145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14146 " %s TDLS set callback Failed",
14147 __func__);
14148 return -EINVAL;
14149 }
14150 return(0);
14151
14152}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014153static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014154 u8 *peer, enum nl80211_tdls_operation oper)
14155{
14156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14157 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014158 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014159 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014160
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14162 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14163 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014164 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014165 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014167 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014168 return -EINVAL;
14169 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014171 status = wlan_hdd_validate_context(pHddCtx);
14172
14173 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14176 "%s: HDD context is not valid", __func__);
14177 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014178 }
14179
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014180
14181 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014182 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014183 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014185 "TDLS Disabled in INI OR not enabled in FW. "
14186 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014187 return -ENOTSUPP;
14188 }
14189
14190 switch (oper) {
14191 case NL80211_TDLS_ENABLE_LINK:
14192 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014193 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014194 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014195 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish315ac822014-12-29 22:01:11 +053014196 WLAN_STADescType staDesc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014197
Sunil Dutt41de4e22013-11-14 18:09:02 +053014198 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish315ac822014-12-29 22:01:11 +053014199 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014200 if ( NULL == pTdlsPeer ) {
14201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14202 " (oper %d) not exsting. ignored",
14203 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14204 return -EINVAL;
14205 }
14206
14207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14208 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14209 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14210 "NL80211_TDLS_ENABLE_LINK");
14211
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014212 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14213 {
14214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14215 MAC_ADDRESS_STR " failed",
14216 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14217 return -EINVAL;
14218 }
14219
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014220 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014221 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014222 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014223
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014224 if (0 != wlan_hdd_tdls_get_link_establish_params(
14225 pAdapter, peer,&tdlsLinkEstablishParams)) {
14226 return -EINVAL;
14227 }
14228 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014229
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014230 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14231 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14232 /* Send TDLS peer UAPSD capabilities to the firmware and
14233 * register with the TL on after the response for this operation
14234 * is received .
14235 */
14236 ret = wait_for_completion_interruptible_timeout(
14237 &pAdapter->tdls_link_establish_req_comp,
14238 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14239 if (ret <= 0)
14240 {
14241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14242 "%s: Link Establish Request Faled Status %ld",
14243 __func__, ret);
14244 return -EINVAL;
14245 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014246 }
Atul Mittal115287b2014-07-08 13:26:33 +053014247 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14248 eTDLS_LINK_CONNECTED,
14249 eTDLS_LINK_SUCCESS);
Agarwal Ashish315ac822014-12-29 22:01:11 +053014250 staDesc.ucSTAId = pTdlsPeer->staId;
14251 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14252 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14253 &staDesc);
14254
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014255 /* Mark TDLS client Authenticated .*/
14256 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14257 pTdlsPeer->staId,
14258 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014259 if (VOS_STATUS_SUCCESS == status)
14260 {
Hoonki Lee14621352013-04-16 17:51:19 -070014261 if (pTdlsPeer->is_responder == 0)
14262 {
14263 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14264
14265 wlan_hdd_tdls_timer_restart(pAdapter,
14266 &pTdlsPeer->initiatorWaitTimeoutTimer,
14267 WAIT_TIME_TDLS_INITIATOR);
14268 /* suspend initiator TX until it receives direct packet from the
14269 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14270 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14271 &staId, NULL);
14272 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014273 wlan_hdd_tdls_increment_peer_count(pAdapter);
14274 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014275 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014276
14277 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014278 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14279 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014280 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014281 int ac;
14282 uint8 ucAc[4] = { WLANTL_AC_VO,
14283 WLANTL_AC_VI,
14284 WLANTL_AC_BK,
14285 WLANTL_AC_BE };
14286 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14287 for(ac=0; ac < 4; ac++)
14288 {
14289 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14290 pTdlsPeer->staId, ucAc[ac],
14291 tlTid[ac], tlTid[ac], 0, 0,
14292 WLANTL_BI_DIR );
14293 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014294 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014295 }
14296
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014297 }
14298 break;
14299 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014300 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053014301 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14302
14303 if ( NULL == pTdlsPeer ) {
14304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14305 " (oper %d) not exsting. ignored",
14306 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14307 return -EINVAL;
14308 }
14309
14310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14311 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14312 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14313 "NL80211_TDLS_DISABLE_LINK");
14314
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014315 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014316 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014317 long status;
14318
Atul Mittal271a7652014-09-12 13:18:22 +053014319
14320 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14321 eTDLS_LINK_TEARING,
14322 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14323 eTDLS_LINK_UNSPECIFIED:
14324 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014325 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14326
Lee Hoonkic1262f22013-01-24 21:59:00 -080014327 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14328 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014329
14330 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14331 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014332 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal73145162014-10-10 11:03:46 +053014333 eTDLS_LINK_IDLE,
14334 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014335 if (status <= 0)
14336 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14338 "%s: Del station failed status %ld",
14339 __func__, status);
14340 return -EPERM;
14341 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014342 }
14343 else
14344 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14346 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014347 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014348 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014349 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014350 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014351 {
Atul Mittal115287b2014-07-08 13:26:33 +053014352 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014353
Atul Mittal115287b2014-07-08 13:26:33 +053014354 if (0 != status)
14355 {
14356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14357 "%s: Error in TDLS Teardown", __func__);
14358 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014359 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014360 break;
14361 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014362 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014363 {
Atul Mittal115287b2014-07-08 13:26:33 +053014364 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14365 peer,
14366 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014367
Atul Mittal115287b2014-07-08 13:26:33 +053014368 if (0 != status)
14369 {
14370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14371 "%s: Error in TDLS Setup", __func__);
14372 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014373 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014374 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014375 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014376 case NL80211_TDLS_DISCOVERY_REQ:
14377 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14379 "%s: We don't support in-driver setup/teardown/discovery "
14380 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014381 return -ENOTSUPP;
14382 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14384 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014385 return -ENOTSUPP;
14386 }
14387 return 0;
14388}
Chilam NG571c65a2013-01-19 12:27:36 +053014389
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014390static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14391 u8 *peer, enum nl80211_tdls_operation oper)
14392{
14393 int ret;
14394
14395 vos_ssr_protect(__func__);
14396 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14397 vos_ssr_unprotect(__func__);
14398
14399 return ret;
14400}
14401
Chilam NG571c65a2013-01-19 12:27:36 +053014402int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14403 struct net_device *dev, u8 *peer)
14404{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014405 hddLog(VOS_TRACE_LEVEL_INFO,
14406 "tdls send discover req: "MAC_ADDRESS_STR,
14407 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014408
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014409#if TDLS_MGMT_VERSION2
14410 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14411 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14412#else
Chilam NG571c65a2013-01-19 12:27:36 +053014413 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14414 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014415#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014416}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014417#endif
14418
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014419#ifdef WLAN_FEATURE_GTK_OFFLOAD
14420/*
14421 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14422 * Callback rountine called upon receiving response for
14423 * get offload info
14424 */
14425void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14426 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14427{
14428
14429 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014430 tANI_U8 tempReplayCounter[8];
14431 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014432
14433 ENTER();
14434
14435 if (NULL == pAdapter)
14436 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014438 "%s: HDD adapter is Null", __func__);
14439 return ;
14440 }
14441
14442 if (NULL == pGtkOffloadGetInfoRsp)
14443 {
14444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14445 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14446 return ;
14447 }
14448
14449 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14450 {
14451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14452 "%s: wlan Failed to get replay counter value",
14453 __func__);
14454 return ;
14455 }
14456
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014457 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14458 /* Update replay counter */
14459 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14460 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14461
14462 {
14463 /* changing from little to big endian since supplicant
14464 * works on big endian format
14465 */
14466 int i;
14467 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14468
14469 for (i = 0; i < 8; i++)
14470 {
14471 tempReplayCounter[7-i] = (tANI_U8)p[i];
14472 }
14473 }
14474
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014475 /* Update replay counter to NL */
14476 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014477 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014478}
14479
14480/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014481 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014482 * This function is used to offload GTK rekeying job to the firmware.
14483 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014484int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014485 struct cfg80211_gtk_rekey_data *data)
14486{
14487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14488 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14489 hdd_station_ctx_t *pHddStaCtx;
14490 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014491 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014492 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014493 eHalStatus status = eHAL_STATUS_FAILURE;
14494
14495 ENTER();
14496
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014497
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014498 if (NULL == pAdapter)
14499 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014501 "%s: HDD adapter is Null", __func__);
14502 return -ENODEV;
14503 }
14504
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14506 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14507 pAdapter->sessionId, pAdapter->device_mode));
14508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014509 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014510
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014511 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014512 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14514 "%s: HDD context is not valid", __func__);
14515 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014516 }
14517
14518 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14519 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14520 if (NULL == hHal)
14521 {
14522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14523 "%s: HAL context is Null!!!", __func__);
14524 return -EAGAIN;
14525 }
14526
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014527 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14528 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14529 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14530 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014531 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014532 {
14533 /* changing from big to little endian since driver
14534 * works on little endian format
14535 */
14536 tANI_U8 *p =
14537 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14538 int i;
14539
14540 for (i = 0; i < 8; i++)
14541 {
14542 p[7-i] = data->replay_ctr[i];
14543 }
14544 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014545
14546 if (TRUE == pHddCtx->hdd_wlan_suspended)
14547 {
14548 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014549 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14550 sizeof (tSirGtkOffloadParams));
14551 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014552 pAdapter->sessionId);
14553
14554 if (eHAL_STATUS_SUCCESS != status)
14555 {
14556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14557 "%s: sme_SetGTKOffload failed, returned %d",
14558 __func__, status);
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +053014559
14560 /* Need to clear any trace of key value in the memory.
14561 * Thus zero out the memory even though it is local
14562 * variable.
14563 */
14564 vos_mem_zero(&hddGtkOffloadReqParams,
14565 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014566 return status;
14567 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14569 "%s: sme_SetGTKOffload successfull", __func__);
14570 }
14571 else
14572 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14574 "%s: wlan not suspended GTKOffload request is stored",
14575 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014576 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014577
Vinay Krishna Eranna3d44f1e2014-10-13 16:03:06 +053014578 /* Need to clear any trace of key value in the memory.
14579 * Thus zero out the memory even though it is local
14580 * variable.
14581 */
14582 vos_mem_zero(&hddGtkOffloadReqParams,
14583 sizeof(hddGtkOffloadReqParams));
14584
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014585 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014586}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014587
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014588int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14589 struct cfg80211_gtk_rekey_data *data)
14590{
14591 int ret;
14592
14593 vos_ssr_protect(__func__);
14594 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14595 vos_ssr_unprotect(__func__);
14596
14597 return ret;
14598}
14599#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014600/*
14601 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
14602 * This function is used to set access control policy
14603 */
14604static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
14605 struct net_device *dev, const struct cfg80211_acl_data *params)
14606{
14607 int i;
14608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14609 hdd_hostapd_state_t *pHostapdState;
14610 tsap_Config_t *pConfig;
14611 v_CONTEXT_t pVosContext = NULL;
14612 hdd_context_t *pHddCtx;
14613 int status;
14614
14615 ENTER();
14616
14617 if (NULL == pAdapter)
14618 {
14619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14620 "%s: HDD adapter is Null", __func__);
14621 return -ENODEV;
14622 }
14623
14624 if (NULL == params)
14625 {
14626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14627 "%s: params is Null", __func__);
14628 return -EINVAL;
14629 }
14630
14631 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14632 status = wlan_hdd_validate_context(pHddCtx);
14633
14634 if (0 != status)
14635 {
14636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14637 "%s: HDD context is not valid", __func__);
14638 return status;
14639 }
14640
14641 pVosContext = pHddCtx->pvosContext;
14642 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
14643
14644 if (NULL == pHostapdState)
14645 {
14646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14647 "%s: pHostapdState is Null", __func__);
14648 return -EINVAL;
14649 }
14650
14651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
14652 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
14653
14654 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
14655 {
14656 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
14657
14658 /* default value */
14659 pConfig->num_accept_mac = 0;
14660 pConfig->num_deny_mac = 0;
14661
14662 /**
14663 * access control policy
14664 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
14665 * listed in hostapd.deny file.
14666 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
14667 * listed in hostapd.accept file.
14668 */
14669 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
14670 {
14671 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
14672 }
14673 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
14674 {
14675 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
14676 }
14677 else
14678 {
14679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14680 "%s:Acl Policy : %d is not supported",
14681 __func__, params->acl_policy);
14682 return -ENOTSUPP;
14683 }
14684
14685 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
14686 {
14687 pConfig->num_accept_mac = params->n_acl_entries;
14688 for (i = 0; i < params->n_acl_entries; i++)
14689 {
14690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14691 "** Add ACL MAC entry %i in WhiletList :"
14692 MAC_ADDRESS_STR, i,
14693 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14694
14695 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
14696 sizeof(qcmacaddr));
14697 }
14698 }
14699 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
14700 {
14701 pConfig->num_deny_mac = params->n_acl_entries;
14702 for (i = 0; i < params->n_acl_entries; i++)
14703 {
14704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14705 "** Add ACL MAC entry %i in BlackList :"
14706 MAC_ADDRESS_STR, i,
14707 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
14708
14709 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
14710 sizeof(qcmacaddr));
14711 }
14712 }
14713
14714 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
14715 {
14716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14717 "%s: SAP Set Mac Acl fail", __func__);
14718 return -EINVAL;
14719 }
14720 }
14721 else
14722 {
14723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014724 "%s: Invalid device_mode = %s (%d)",
14725 __func__, hdd_device_modetoString(pAdapter->device_mode),
14726 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014727 return -EINVAL;
14728 }
14729
14730 return 0;
14731}
14732
Leo Chang9056f462013-08-01 19:21:11 -070014733#ifdef WLAN_NL80211_TESTMODE
14734#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070014735void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070014736(
14737 void *pAdapter,
14738 void *indCont
14739)
14740{
Leo Changd9df8aa2013-09-26 13:32:26 -070014741 tSirLPHBInd *lphbInd;
14742 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053014743 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070014744
14745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014746 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070014747
c_hpothu73f35e62014-04-18 13:40:08 +053014748 if (pAdapter == NULL)
14749 {
14750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14751 "%s: pAdapter is NULL\n",__func__);
14752 return;
14753 }
14754
Leo Chang9056f462013-08-01 19:21:11 -070014755 if (NULL == indCont)
14756 {
14757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070014758 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070014759 return;
14760 }
14761
c_hpothu73f35e62014-04-18 13:40:08 +053014762 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070014763 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070014764 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053014765 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070014766 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070014767 GFP_ATOMIC);
14768 if (!skb)
14769 {
14770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14771 "LPHB timeout, NL buffer alloc fail");
14772 return;
14773 }
14774
Leo Changac3ba772013-10-07 09:47:04 -070014775 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070014776 {
14777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14778 "WLAN_HDD_TM_ATTR_CMD put fail");
14779 goto nla_put_failure;
14780 }
Leo Changac3ba772013-10-07 09:47:04 -070014781 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070014782 {
14783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14784 "WLAN_HDD_TM_ATTR_TYPE put fail");
14785 goto nla_put_failure;
14786 }
Leo Changac3ba772013-10-07 09:47:04 -070014787 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070014788 sizeof(tSirLPHBInd), lphbInd))
14789 {
14790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14791 "WLAN_HDD_TM_ATTR_DATA put fail");
14792 goto nla_put_failure;
14793 }
Leo Chang9056f462013-08-01 19:21:11 -070014794 cfg80211_testmode_event(skb, GFP_ATOMIC);
14795 return;
14796
14797nla_put_failure:
14798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14799 "NLA Put fail");
14800 kfree_skb(skb);
14801
14802 return;
14803}
14804#endif /* FEATURE_WLAN_LPHB */
14805
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014806static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070014807{
14808 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
14809 int err = 0;
14810#ifdef FEATURE_WLAN_LPHB
14811 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070014812 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070014813#endif /* FEATURE_WLAN_LPHB */
14814
14815 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
14816 if (err)
14817 {
14818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14819 "%s Testmode INV ATTR", __func__);
14820 return err;
14821 }
14822
14823 if (!tb[WLAN_HDD_TM_ATTR_CMD])
14824 {
14825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14826 "%s Testmode INV CMD", __func__);
14827 return -EINVAL;
14828 }
14829
14830 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
14831 {
14832#ifdef FEATURE_WLAN_LPHB
14833 /* Low Power Heartbeat configuration request */
14834 case WLAN_HDD_TM_CMD_WLAN_HB:
14835 {
14836 int buf_len;
14837 void *buf;
14838 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080014839 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070014840
14841 if (!tb[WLAN_HDD_TM_ATTR_DATA])
14842 {
14843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14844 "%s Testmode INV DATA", __func__);
14845 return -EINVAL;
14846 }
14847
14848 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
14849 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080014850
14851 hb_params_temp =(tSirLPHBReq *)buf;
14852 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
14853 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
14854 return -EINVAL;
14855
Leo Chang9056f462013-08-01 19:21:11 -070014856 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
14857 if (NULL == hb_params)
14858 {
14859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14860 "%s Request Buffer Alloc Fail", __func__);
14861 return -EINVAL;
14862 }
14863
14864 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070014865 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
14866 hb_params,
14867 wlan_hdd_cfg80211_lphb_ind_handler);
14868 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070014869 {
Leo Changd9df8aa2013-09-26 13:32:26 -070014870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14871 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070014872 vos_mem_free(hb_params);
14873 }
Leo Chang9056f462013-08-01 19:21:11 -070014874 return 0;
14875 }
14876#endif /* FEATURE_WLAN_LPHB */
14877 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14879 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070014880 return -EOPNOTSUPP;
14881 }
14882
14883 return err;
14884}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014885
14886static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
14887{
14888 int ret;
14889
14890 vos_ssr_protect(__func__);
14891 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
14892 vos_ssr_unprotect(__func__);
14893
14894 return ret;
14895}
Leo Chang9056f462013-08-01 19:21:11 -070014896#endif /* CONFIG_NL80211_TESTMODE */
14897
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014898static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014899 struct net_device *dev,
14900 int idx, struct survey_info *survey)
14901{
14902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14903 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053014904 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014905 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053014906 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014907 v_S7_t snr,rssi;
14908 int status, i, j, filled = 0;
14909
14910 ENTER();
14911
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014912 if (NULL == pAdapter)
14913 {
14914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14915 "%s: HDD adapter is Null", __func__);
14916 return -ENODEV;
14917 }
14918
14919 if (NULL == wiphy)
14920 {
14921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14922 "%s: wiphy is Null", __func__);
14923 return -ENODEV;
14924 }
14925
14926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14927 status = wlan_hdd_validate_context(pHddCtx);
14928
14929 if (0 != status)
14930 {
14931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14932 "%s: HDD context is not valid", __func__);
14933 return status;
14934 }
14935
Mihir Sheted9072e02013-08-21 17:02:29 +053014936 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14937
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014938 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053014939 0 != pAdapter->survey_idx ||
14940 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014941 {
14942 /* The survey dump ops when implemented completely is expected to
14943 * return a survey of all channels and the ops is called by the
14944 * kernel with incremental values of the argument 'idx' till it
14945 * returns -ENONET. But we can only support the survey for the
14946 * operating channel for now. survey_idx is used to track
14947 * that the ops is called only once and then return -ENONET for
14948 * the next iteration
14949 */
14950 pAdapter->survey_idx = 0;
14951 return -ENONET;
14952 }
14953
14954 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14955
14956 wlan_hdd_get_snr(pAdapter, &snr);
14957 wlan_hdd_get_rssi(pAdapter, &rssi);
14958
14959 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
14960 hdd_wlan_get_freq(channel, &freq);
14961
14962
14963 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
14964 {
14965 if (NULL == wiphy->bands[i])
14966 {
14967 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
14968 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
14969 continue;
14970 }
14971
14972 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
14973 {
14974 struct ieee80211_supported_band *band = wiphy->bands[i];
14975
14976 if (band->channels[j].center_freq == (v_U16_t)freq)
14977 {
14978 survey->channel = &band->channels[j];
14979 /* The Rx BDs contain SNR values in dB for the received frames
14980 * while the supplicant expects noise. So we calculate and
14981 * return the value of noise (dBm)
14982 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
14983 */
14984 survey->noise = rssi - snr;
14985 survey->filled = SURVEY_INFO_NOISE_DBM;
14986 filled = 1;
14987 }
14988 }
14989 }
14990
14991 if (filled)
14992 pAdapter->survey_idx = 1;
14993 else
14994 {
14995 pAdapter->survey_idx = 0;
14996 return -ENONET;
14997 }
14998
14999 return 0;
15000}
15001
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015002static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15003 struct net_device *dev,
15004 int idx, struct survey_info *survey)
15005{
15006 int ret;
15007
15008 vos_ssr_protect(__func__);
15009 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15010 vos_ssr_unprotect(__func__);
15011
15012 return ret;
15013}
15014
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015015/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015016 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015017 * this is called when cfg80211 driver resume
15018 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15019 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015020int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015021{
15022 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15023 hdd_adapter_t *pAdapter;
15024 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15025 VOS_STATUS status = VOS_STATUS_SUCCESS;
15026
15027 ENTER();
15028
15029 if ( NULL == pHddCtx )
15030 {
15031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15032 "%s: HddCtx validation failed", __func__);
15033 return 0;
15034 }
15035
15036 if (pHddCtx->isLogpInProgress)
15037 {
15038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15039 "%s: LOGP in Progress. Ignore!!!", __func__);
15040 return 0;
15041 }
15042
Mihir Shete18156292014-03-11 15:38:30 +053015043 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015044 {
15045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15046 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15047 return 0;
15048 }
15049
15050 spin_lock(&pHddCtx->schedScan_lock);
15051 pHddCtx->isWiphySuspended = FALSE;
15052 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15053 {
15054 spin_unlock(&pHddCtx->schedScan_lock);
15055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15056 "%s: Return resume is not due to PNO indication", __func__);
15057 return 0;
15058 }
15059 // Reset flag to avoid updatating cfg80211 data old results again
15060 pHddCtx->isSchedScanUpdatePending = FALSE;
15061 spin_unlock(&pHddCtx->schedScan_lock);
15062
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015063
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015064 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15065
15066 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15067 {
15068 pAdapter = pAdapterNode->pAdapter;
15069 if ( (NULL != pAdapter) &&
15070 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15071 {
15072 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015073 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15075 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015076 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015077 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015078 {
15079 /* Acquire wakelock to handle the case where APP's tries to
15080 * suspend immediately after updating the scan results. Whis
15081 * results in app's is in suspended state and not able to
15082 * process the connect request to AP
15083 */
15084 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015085 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015086 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015087
15088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15089 "%s : cfg80211 scan result database updated", __func__);
15090
15091 return 0;
15092
15093 }
15094 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15095 pAdapterNode = pNext;
15096 }
15097
15098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15099 "%s: Failed to find Adapter", __func__);
15100 return 0;
15101}
15102
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015103int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15104{
15105 int ret;
15106
15107 vos_ssr_protect(__func__);
15108 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15109 vos_ssr_unprotect(__func__);
15110
15111 return ret;
15112}
15113
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015114/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015115 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015116 * this is called when cfg80211 driver suspends
15117 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015118int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015119 struct cfg80211_wowlan *wow)
15120{
15121 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15122
15123 ENTER();
15124 if (NULL == pHddCtx)
15125 {
15126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15127 "%s: HddCtx validation failed", __func__);
15128 return 0;
15129 }
15130
15131 pHddCtx->isWiphySuspended = TRUE;
15132
15133 EXIT();
15134
15135 return 0;
15136}
15137
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015138int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15139 struct cfg80211_wowlan *wow)
15140{
15141 int ret;
15142
15143 vos_ssr_protect(__func__);
15144 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15145 vos_ssr_unprotect(__func__);
15146
15147 return ret;
15148}
Jeff Johnson295189b2012-06-20 16:38:30 -070015149/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015150static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015151{
15152 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15153 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15154 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15155 .change_station = wlan_hdd_change_station,
15156#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15157 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15158 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15159 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015160#else
15161 .start_ap = wlan_hdd_cfg80211_start_ap,
15162 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15163 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015164#endif
15165 .change_bss = wlan_hdd_cfg80211_change_bss,
15166 .add_key = wlan_hdd_cfg80211_add_key,
15167 .get_key = wlan_hdd_cfg80211_get_key,
15168 .del_key = wlan_hdd_cfg80211_del_key,
15169 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015170#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015171 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015172#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015173 .scan = wlan_hdd_cfg80211_scan,
15174 .connect = wlan_hdd_cfg80211_connect,
15175 .disconnect = wlan_hdd_cfg80211_disconnect,
15176 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15177 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15178 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15179 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15180 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015181 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15182 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015183 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15185 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15186 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15187 .set_txq_params = wlan_hdd_set_txq_params,
15188#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015189 .get_station = wlan_hdd_cfg80211_get_station,
15190 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15191 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015192 .add_station = wlan_hdd_cfg80211_add_station,
15193#ifdef FEATURE_WLAN_LFR
15194 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15195 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15196 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15197#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015198#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15199 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15200#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015201#ifdef FEATURE_WLAN_TDLS
15202 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15203 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15204#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015205#ifdef WLAN_FEATURE_GTK_OFFLOAD
15206 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15207#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015208#ifdef FEATURE_WLAN_SCAN_PNO
15209 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15210 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15211#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015212 .resume = wlan_hdd_cfg80211_resume_wlan,
15213 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015214 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015215#ifdef WLAN_NL80211_TESTMODE
15216 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15217#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015218 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015219};
15220