blob: cb2bba94484008c8d86c3519057c87eb573786d1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#ifdef FEATURE_WLAN_TDLS
94#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080097#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053098#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070099#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700100
101#define g_mode_rates_size (12)
102#define a_mode_rates_size (8)
103#define FREQ_BASE_80211G (2407)
104#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700105#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530106#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800108 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700109
110#define HDD2GHZCHAN(freq, chan, flag) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (freq), \
113 .hw_value = (chan),\
114 .flags = (flag), \
115 .max_antenna_gain = 0 ,\
116 .max_power = 30, \
117}
118
119#define HDD5GHZCHAN(freq, chan, flag) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = (freq), \
122 .hw_value = (chan),\
123 .flags = (flag), \
124 .max_antenna_gain = 0 ,\
125 .max_power = 30, \
126}
127
128#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
129{\
130 .bitrate = rate, \
131 .hw_value = rate_id, \
132 .flags = flag, \
133}
134
Lee Hoonkic1262f22013-01-24 21:59:00 -0800135#ifndef WLAN_FEATURE_TDLS_DEBUG
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
137#else
138#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
139#endif
140
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530141#ifdef WLAN_FEATURE_VOWIFI_11R
142#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
143#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
144#endif
145
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530146#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530147#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530148
Sunil Duttc69bccb2014-05-26 21:30:20 +0530149#ifdef WLAN_FEATURE_LINK_LAYER_STATS
150/*
151 * Used to allocate the size of 4096 for the link layer stats.
152 * The size of 4096 is considered assuming that all data per
153 * respective event fit with in the limit.Please take a call
154 * on the limit based on the data requirements on link layer
155 * statistics.
156 */
157#define LL_STATS_EVENT_BUF_SIZE 4096
158#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530159#ifdef WLAN_FEATURE_EXTSCAN
160/*
161 * Used to allocate the size of 4096 for the EXTScan NL data.
162 * The size of 4096 is considered assuming that all data per
163 * respective event fit with in the limit.Please take a call
164 * on the limit based on the data requirements.
165 */
166
167#define EXTSCAN_EVENT_BUF_SIZE 4096
168#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
169#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530170
Atul Mittal115287b2014-07-08 13:26:33 +0530171/*EXT TDLS*/
172/*
173 * Used to allocate the size of 4096 for the TDLS.
174 * The size of 4096 is considered assuming that all data per
175 * respective event fit with in the limit.Please take a call
176 * on the limit based on the data requirements on link layer
177 * statistics.
178 */
179#define EXTTDLS_EVENT_BUF_SIZE 4096
180
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530181static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700182{
183 WLAN_CIPHER_SUITE_WEP40,
184 WLAN_CIPHER_SUITE_WEP104,
185 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700187#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
188 WLAN_CIPHER_SUITE_KRK,
189 WLAN_CIPHER_SUITE_CCMP,
190#else
191 WLAN_CIPHER_SUITE_CCMP,
192#endif
193#ifdef FEATURE_WLAN_WAPI
194 WLAN_CIPHER_SUITE_SMS4,
195#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700196#ifdef WLAN_FEATURE_11W
197 WLAN_CIPHER_SUITE_AES_CMAC,
198#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700199};
200
201static inline int is_broadcast_ether_addr(const u8 *addr)
202{
203 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
204 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
205}
206
207static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530208{
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 HDD2GHZCHAN(2412, 1, 0) ,
210 HDD2GHZCHAN(2417, 2, 0) ,
211 HDD2GHZCHAN(2422, 3, 0) ,
212 HDD2GHZCHAN(2427, 4, 0) ,
213 HDD2GHZCHAN(2432, 5, 0) ,
214 HDD2GHZCHAN(2437, 6, 0) ,
215 HDD2GHZCHAN(2442, 7, 0) ,
216 HDD2GHZCHAN(2447, 8, 0) ,
217 HDD2GHZCHAN(2452, 9, 0) ,
218 HDD2GHZCHAN(2457, 10, 0) ,
219 HDD2GHZCHAN(2462, 11, 0) ,
220 HDD2GHZCHAN(2467, 12, 0) ,
221 HDD2GHZCHAN(2472, 13, 0) ,
222 HDD2GHZCHAN(2484, 14, 0) ,
223};
224
Jeff Johnson295189b2012-06-20 16:38:30 -0700225static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
226{
227 HDD2GHZCHAN(2412, 1, 0) ,
228 HDD2GHZCHAN(2437, 6, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230};
Jeff Johnson295189b2012-06-20 16:38:30 -0700231
232static struct ieee80211_channel hdd_channels_5_GHZ[] =
233{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700234 HDD5GHZCHAN(4920, 240, 0) ,
235 HDD5GHZCHAN(4940, 244, 0) ,
236 HDD5GHZCHAN(4960, 248, 0) ,
237 HDD5GHZCHAN(4980, 252, 0) ,
238 HDD5GHZCHAN(5040, 208, 0) ,
239 HDD5GHZCHAN(5060, 212, 0) ,
240 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 HDD5GHZCHAN(5180, 36, 0) ,
242 HDD5GHZCHAN(5200, 40, 0) ,
243 HDD5GHZCHAN(5220, 44, 0) ,
244 HDD5GHZCHAN(5240, 48, 0) ,
245 HDD5GHZCHAN(5260, 52, 0) ,
246 HDD5GHZCHAN(5280, 56, 0) ,
247 HDD5GHZCHAN(5300, 60, 0) ,
248 HDD5GHZCHAN(5320, 64, 0) ,
249 HDD5GHZCHAN(5500,100, 0) ,
250 HDD5GHZCHAN(5520,104, 0) ,
251 HDD5GHZCHAN(5540,108, 0) ,
252 HDD5GHZCHAN(5560,112, 0) ,
253 HDD5GHZCHAN(5580,116, 0) ,
254 HDD5GHZCHAN(5600,120, 0) ,
255 HDD5GHZCHAN(5620,124, 0) ,
256 HDD5GHZCHAN(5640,128, 0) ,
257 HDD5GHZCHAN(5660,132, 0) ,
258 HDD5GHZCHAN(5680,136, 0) ,
259 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800260#ifdef FEATURE_WLAN_CH144
261 HDD5GHZCHAN(5720,144, 0) ,
262#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 HDD5GHZCHAN(5745,149, 0) ,
264 HDD5GHZCHAN(5765,153, 0) ,
265 HDD5GHZCHAN(5785,157, 0) ,
266 HDD5GHZCHAN(5805,161, 0) ,
267 HDD5GHZCHAN(5825,165, 0) ,
268};
269
270static struct ieee80211_rate g_mode_rates[] =
271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530272 HDD_G_MODE_RATETAB(10, 0x1, 0),
273 HDD_G_MODE_RATETAB(20, 0x2, 0),
274 HDD_G_MODE_RATETAB(55, 0x4, 0),
275 HDD_G_MODE_RATETAB(110, 0x8, 0),
276 HDD_G_MODE_RATETAB(60, 0x10, 0),
277 HDD_G_MODE_RATETAB(90, 0x20, 0),
278 HDD_G_MODE_RATETAB(120, 0x40, 0),
279 HDD_G_MODE_RATETAB(180, 0x80, 0),
280 HDD_G_MODE_RATETAB(240, 0x100, 0),
281 HDD_G_MODE_RATETAB(360, 0x200, 0),
282 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530284};
Jeff Johnson295189b2012-06-20 16:38:30 -0700285
286static struct ieee80211_rate a_mode_rates[] =
287{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530288 HDD_G_MODE_RATETAB(60, 0x10, 0),
289 HDD_G_MODE_RATETAB(90, 0x20, 0),
290 HDD_G_MODE_RATETAB(120, 0x40, 0),
291 HDD_G_MODE_RATETAB(180, 0x80, 0),
292 HDD_G_MODE_RATETAB(240, 0x100, 0),
293 HDD_G_MODE_RATETAB(360, 0x200, 0),
294 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 HDD_G_MODE_RATETAB(540, 0x800, 0),
296};
297
298static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
299{
300 .channels = hdd_channels_2_4_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
302 .band = IEEE80211_BAND_2GHZ,
303 .bitrates = g_mode_rates,
304 .n_bitrates = g_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
310 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
311 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
312 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
313 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
314 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
315};
316
Jeff Johnson295189b2012-06-20 16:38:30 -0700317static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
318{
319 .channels = hdd_social_channels_2_4_GHZ,
320 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
321 .band = IEEE80211_BAND_2GHZ,
322 .bitrates = g_mode_rates,
323 .n_bitrates = g_mode_rates_size,
324 .ht_cap.ht_supported = 1,
325 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
326 | IEEE80211_HT_CAP_GRN_FLD
327 | IEEE80211_HT_CAP_DSSSCCK40
328 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
Jeff Johnson295189b2012-06-20 16:38:30 -0700335
336static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
337{
338 .channels = hdd_channels_5_GHZ,
339 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
340 .band = IEEE80211_BAND_5GHZ,
341 .bitrates = a_mode_rates,
342 .n_bitrates = a_mode_rates_size,
343 .ht_cap.ht_supported = 1,
344 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
345 | IEEE80211_HT_CAP_GRN_FLD
346 | IEEE80211_HT_CAP_DSSSCCK40
347 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
348 | IEEE80211_HT_CAP_SGI_40
349 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
350 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
351 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
352 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
353 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
354 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
355};
356
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530357/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 TX/RX direction for each kind of interface */
359static const struct ieee80211_txrx_stypes
360wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
361 [NL80211_IFTYPE_STATION] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ACTION) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ),
365 },
366 [NL80211_IFTYPE_AP] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
369 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
370 BIT(SIR_MAC_MGMT_PROBE_REQ) |
371 BIT(SIR_MAC_MGMT_DISASSOC) |
372 BIT(SIR_MAC_MGMT_AUTH) |
373 BIT(SIR_MAC_MGMT_DEAUTH) |
374 BIT(SIR_MAC_MGMT_ACTION),
375 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700376 [NL80211_IFTYPE_ADHOC] = {
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386 [NL80211_IFTYPE_P2P_CLIENT] = {
387 .tx = 0xffff,
388 .rx = BIT(SIR_MAC_MGMT_ACTION) |
389 BIT(SIR_MAC_MGMT_PROBE_REQ),
390 },
391 [NL80211_IFTYPE_P2P_GO] = {
392 /* This is also same as for SoftAP */
393 .tx = 0xffff,
394 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
395 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
396 BIT(SIR_MAC_MGMT_PROBE_REQ) |
397 BIT(SIR_MAC_MGMT_DISASSOC) |
398 BIT(SIR_MAC_MGMT_AUTH) |
399 BIT(SIR_MAC_MGMT_DEAUTH) |
400 BIT(SIR_MAC_MGMT_ACTION),
401 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700402};
403
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800405static const struct ieee80211_iface_limit
406wlan_hdd_iface_limit[] = {
407 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800408 /* max = 3 ; Our driver create two interfaces during driver init
409 * wlan0 and p2p0 interfaces. p2p0 is considered as station
410 * interface until a group is formed. In JB architecture, once the
411 * group is formed, interface type of p2p0 is changed to P2P GO or
412 * Client.
413 * When supplicant remove the group, it first issue a set interface
414 * cmd to change the mode back to Station. In JB this works fine as
415 * we advertize two station type interface during driver init.
416 * Some vendors create separate interface for P2P GO/Client,
417 * after group formation(Third one). But while group remove
418 * supplicant first tries to change the mode(3rd interface) to STATION
419 * But as we advertized only two sta type interfaces nl80211 was
420 * returning error for the third one which was leading to failure in
421 * delete interface. Ideally while removing the group, supplicant
422 * should not try to change the 3rd interface mode to Station type.
423 * Till we get a fix in wpa_supplicant, we advertize max STA
424 * interface type to 3
425 */
426 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 .types = BIT(NL80211_IFTYPE_STATION),
428 },
429 {
430 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700431 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432 },
433 {
434 .max = 1,
435 .types = BIT(NL80211_IFTYPE_P2P_GO) |
436 BIT(NL80211_IFTYPE_P2P_CLIENT),
437 },
438};
439
440/* By default, only single channel concurrency is allowed */
441static struct ieee80211_iface_combination
442wlan_hdd_iface_combination = {
443 .limits = wlan_hdd_iface_limit,
444 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800445 /*
446 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
447 * and p2p0 interfaces during driver init
448 * Some vendors create separate interface for P2P operations.
449 * wlan0: STA interface
450 * p2p0: P2P Device interface, action frames goes
451 * through this interface.
452 * p2p-xx: P2P interface, After GO negotiation this interface is
453 * created for p2p operations(GO/CLIENT interface).
454 */
455 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
457 .beacon_int_infra_match = false,
458};
459#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800460
Jeff Johnson295189b2012-06-20 16:38:30 -0700461static struct cfg80211_ops wlan_hdd_cfg80211_ops;
462
463/* Data rate 100KBPS based on IE Index */
464struct index_data_rate_type
465{
466 v_U8_t beacon_rate_index;
467 v_U16_t supported_rate[4];
468};
469
470/* 11B, 11G Rate table include Basic rate and Extended rate
471 The IDX field is the rate index
472 The HI field is the rate when RSSI is strong or being ignored
473 (in this case we report actual rate)
474 The MID field is the rate when RSSI is moderate
475 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
476 The LO field is the rate when RSSI is low
477 (in this case we don't report rates, actual current rate used)
478 */
479static const struct
480{
481 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700482 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700483} supported_data_rate[] =
484{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700485/* IDX HI HM LM LO (RSSI-based index */
486 {2, { 10, 10, 10, 0}},
487 {4, { 20, 20, 10, 0}},
488 {11, { 55, 20, 10, 0}},
489 {12, { 60, 55, 20, 0}},
490 {18, { 90, 55, 20, 0}},
491 {22, {110, 55, 20, 0}},
492 {24, {120, 90, 60, 0}},
493 {36, {180, 120, 60, 0}},
494 {44, {220, 180, 60, 0}},
495 {48, {240, 180, 90, 0}},
496 {66, {330, 180, 90, 0}},
497 {72, {360, 240, 90, 0}},
498 {96, {480, 240, 120, 0}},
499 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700500};
501
502/* MCS Based rate table */
503static struct index_data_rate_type supported_mcs_rate[] =
504{
505/* MCS L20 L40 S20 S40 */
506 {0, {65, 135, 72, 150}},
507 {1, {130, 270, 144, 300}},
508 {2, {195, 405, 217, 450}},
509 {3, {260, 540, 289, 600}},
510 {4, {390, 810, 433, 900}},
511 {5, {520, 1080, 578, 1200}},
512 {6, {585, 1215, 650, 1350}},
513 {7, {650, 1350, 722, 1500}}
514};
515
Leo Chang6f8870f2013-03-26 18:11:36 -0700516#ifdef WLAN_FEATURE_11AC
517
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700519
520struct index_vht_data_rate_type
521{
522 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530523 v_U16_t supported_VHT80_rate[2];
524 v_U16_t supported_VHT40_rate[2];
525 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700526};
527
528typedef enum
529{
530 DATA_RATE_11AC_MAX_MCS_7,
531 DATA_RATE_11AC_MAX_MCS_8,
532 DATA_RATE_11AC_MAX_MCS_9,
533 DATA_RATE_11AC_MAX_MCS_NA
534} eDataRate11ACMaxMcs;
535
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530536/* SSID broadcast type */
537typedef enum eSSIDBcastType
538{
539 eBCAST_UNKNOWN = 0,
540 eBCAST_NORMAL = 1,
541 eBCAST_HIDDEN = 2,
542} tSSIDBcastType;
543
Leo Chang6f8870f2013-03-26 18:11:36 -0700544/* MCS Based VHT rate table */
545static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
546{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530547/* MCS L80 S80 L40 S40 L20 S40*/
548 {0, {293, 325}, {135, 150}, {65, 72}},
549 {1, {585, 650}, {270, 300}, {130, 144}},
550 {2, {878, 975}, {405, 450}, {195, 217}},
551 {3, {1170, 1300}, {540, 600}, {260, 289}},
552 {4, {1755, 1950}, {810, 900}, {390, 433}},
553 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
554 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
555 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
556 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
557 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700558};
559#endif /* WLAN_FEATURE_11AC */
560
c_hpothu79aab322014-07-14 21:11:01 +0530561/*array index points to MCS and array value points respective rssi*/
562static int rssiMcsTbl[][10] =
563{
564/*MCS 0 1 2 3 4 5 6 7 8 9*/
565 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
566 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
567 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
568};
569
Jeff Johnson295189b2012-06-20 16:38:30 -0700570extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530571#ifdef FEATURE_WLAN_SCAN_PNO
572static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700574
Leo Chang9056f462013-08-01 19:21:11 -0700575#ifdef WLAN_NL80211_TESTMODE
576enum wlan_hdd_tm_attr
577{
578 WLAN_HDD_TM_ATTR_INVALID = 0,
579 WLAN_HDD_TM_ATTR_CMD = 1,
580 WLAN_HDD_TM_ATTR_DATA = 2,
581 WLAN_HDD_TM_ATTR_TYPE = 3,
582 /* keep last */
583 WLAN_HDD_TM_ATTR_AFTER_LAST,
584 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
585};
586
587enum wlan_hdd_tm_cmd
588{
589 WLAN_HDD_TM_CMD_WLAN_HB = 1,
590};
591
592#define WLAN_HDD_TM_DATA_MAX_LEN 5000
593
594static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
595{
596 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
597 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
598 .len = WLAN_HDD_TM_DATA_MAX_LEN },
599};
600#endif /* WLAN_NL80211_TESTMODE */
601
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800602#ifdef FEATURE_WLAN_CH_AVOID
603/*
604 * FUNCTION: wlan_hdd_send_avoid_freq_event
605 * This is called when wlan driver needs to send vendor specific
606 * avoid frequency range event to userspace
607 */
608int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
609 tHddAvoidFreqList *pAvoidFreqList)
610{
611 struct sk_buff *vendor_event;
612
613 ENTER();
614
615 if (!pHddCtx)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
618 "%s: HDD context is null", __func__);
619 return -1;
620 }
621
622 if (!pAvoidFreqList)
623 {
624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
625 "%s: pAvoidFreqList is null", __func__);
626 return -1;
627 }
628
629 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
630 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530631 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800632 GFP_KERNEL);
633 if (!vendor_event)
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: cfg80211_vendor_event_alloc failed", __func__);
637 return -1;
638 }
639
640 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
641 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
642
643 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
644
645 EXIT();
646 return 0;
647}
648#endif /* FEATURE_WLAN_CH_AVOID */
649
Sunil Duttc69bccb2014-05-26 21:30:20 +0530650#ifdef WLAN_FEATURE_LINK_LAYER_STATS
651
652static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
653 struct sk_buff *vendor_event)
654{
655 if (nla_put_u8(vendor_event,
656 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
657 stats->rate.preamble) ||
658 nla_put_u8(vendor_event,
659 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
660 stats->rate.nss) ||
661 nla_put_u8(vendor_event,
662 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
663 stats->rate.bw) ||
664 nla_put_u8(vendor_event,
665 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
666 stats->rate.rateMcsIdx) ||
667 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
668 stats->rate.bitrate ) ||
669 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
670 stats->txMpdu ) ||
671 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
672 stats->rxMpdu ) ||
673 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
674 stats->mpduLost ) ||
675 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
676 stats->retries) ||
677 nla_put_u32(vendor_event,
678 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
679 stats->retriesShort ) ||
680 nla_put_u32(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
682 stats->retriesLong))
683 {
684 hddLog(VOS_TRACE_LEVEL_ERROR,
685 FL("QCA_WLAN_VENDOR_ATTR put fail"));
686 return FALSE;
687 }
688 return TRUE;
689}
690
691static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
692 struct sk_buff *vendor_event)
693{
694 u32 i = 0;
695 struct nlattr *rateInfo;
696 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
697 stats->type) ||
698 nla_put(vendor_event,
699 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
700 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
701 nla_put_u32(vendor_event,
702 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
703 stats->capabilities) ||
704 nla_put_u32(vendor_event,
705 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
706 stats->numRate))
707 {
708 hddLog(VOS_TRACE_LEVEL_ERROR,
709 FL("QCA_WLAN_VENDOR_ATTR put fail"));
710 goto error;
711 }
712
713 rateInfo = nla_nest_start(vendor_event,
714 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530715 if(!rateInfo)
716 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530717 for (i = 0; i < stats->numRate; i++)
718 {
719 struct nlattr *rates;
720 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
721 stats->rateStats +
722 (i * sizeof(tSirWifiRateStat)));
723 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530724 if(!rates)
725 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530726
727 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
728 {
729 hddLog(VOS_TRACE_LEVEL_ERROR,
730 FL("QCA_WLAN_VENDOR_ATTR put fail"));
731 return FALSE;
732 }
733 nla_nest_end(vendor_event, rates);
734 }
735 nla_nest_end(vendor_event, rateInfo);
736
737 return TRUE;
738error:
739 return FALSE;
740}
741
742static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
743 struct sk_buff *vendor_event)
744{
745 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
746 stats->ac ) ||
747 nla_put_u32(vendor_event,
748 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
749 stats->txMpdu ) ||
750 nla_put_u32(vendor_event,
751 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
752 stats->rxMpdu ) ||
753 nla_put_u32(vendor_event,
754 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
755 stats->txMcast ) ||
756 nla_put_u32(vendor_event,
757 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
758 stats->rxMcast ) ||
759 nla_put_u32(vendor_event,
760 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
761 stats->rxAmpdu ) ||
762 nla_put_u32(vendor_event,
763 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
764 stats->txAmpdu ) ||
765 nla_put_u32(vendor_event,
766 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
767 stats->mpduLost )||
768 nla_put_u32(vendor_event,
769 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
770 stats->retries ) ||
771 nla_put_u32(vendor_event,
772 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
773 stats->retriesShort ) ||
774 nla_put_u32(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
776 stats->retriesLong ) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
779 stats->contentionTimeMin ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
782 stats->contentionTimeMax ) ||
783 nla_put_u32(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
785 stats->contentionTimeAvg ) ||
786 nla_put_u32(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
788 stats->contentionNumSamples ))
789 {
790 hddLog(VOS_TRACE_LEVEL_ERROR,
791 FL("QCA_WLAN_VENDOR_ATTR put fail") );
792 return FALSE;
793 }
794 return TRUE;
795}
796
797static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
798 struct sk_buff *vendor_event)
799{
Dino Myclec8f3f332014-07-21 16:48:27 +0530800 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530801 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
802 nla_put(vendor_event,
803 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
804 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
805 nla_put_u32(vendor_event,
806 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
807 stats->state ) ||
808 nla_put_u32(vendor_event,
809 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
810 stats->roaming ) ||
811 nla_put_u32(vendor_event,
812 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
813 stats->capabilities ) ||
814 nla_put(vendor_event,
815 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
816 strlen(stats->ssid), stats->ssid) ||
817 nla_put(vendor_event,
818 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
819 WNI_CFG_BSSID_LEN, stats->bssid) ||
820 nla_put(vendor_event,
821 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
822 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
823 nla_put(vendor_event,
824 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
825 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
826 )
827 {
828 hddLog(VOS_TRACE_LEVEL_ERROR,
829 FL("QCA_WLAN_VENDOR_ATTR put fail") );
830 return FALSE;
831 }
832 return TRUE;
833}
834
Dino Mycle3b9536d2014-07-09 22:05:24 +0530835static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
836 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530837 struct sk_buff *vendor_event)
838{
839 int i = 0;
840 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530841 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
842 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530843 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530844
Sunil Duttc69bccb2014-05-26 21:30:20 +0530845 if (FALSE == put_wifi_interface_info(
846 &pWifiIfaceStat->info,
847 vendor_event))
848 {
849 hddLog(VOS_TRACE_LEVEL_ERROR,
850 FL("QCA_WLAN_VENDOR_ATTR put fail") );
851 return FALSE;
852
853 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530854 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
855 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
856 if (NULL == pWifiIfaceStatTL)
857 {
858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
859 return FALSE;
860 }
861
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530862 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
863 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
864 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
865 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
866
867 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
868 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
869 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
870 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530871
872 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
873 {
874 if (VOS_STATUS_SUCCESS ==
875 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
876 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
877 {
878 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
879 * obtained from TL structure
880 */
881
882 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
883 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530884 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
885
Srinivas Dasari98947432014-11-07 19:41:24 +0530886 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
887 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
888 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
889 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
890 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
891 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
892 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
893 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530894
Srinivas Dasari98947432014-11-07 19:41:24 +0530895 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
896 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
897 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
898 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
899 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
900 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
901 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
902 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530903
Srinivas Dasari98947432014-11-07 19:41:24 +0530904 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
905 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
906 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
907 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
908 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
909 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
910 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
911 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530912 }
913 else
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
916 }
917
Dino Mycle3b9536d2014-07-09 22:05:24 +0530918 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
919 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
920 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
921 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
922 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
923 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
924 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
925 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
926 }
927 else
928 {
929 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
930 }
931
932
Sunil Duttc69bccb2014-05-26 21:30:20 +0530933
934 if (nla_put_u32(vendor_event,
935 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
936 pWifiIfaceStat->beaconRx) ||
937 nla_put_u32(vendor_event,
938 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
939 pWifiIfaceStat->mgmtRx) ||
940 nla_put_u32(vendor_event,
941 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
942 pWifiIfaceStat->mgmtActionRx) ||
943 nla_put_u32(vendor_event,
944 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
945 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530946 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530947 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
948 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530949 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530950 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
951 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +0530952 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530953 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
954 pWifiIfaceStat->rssiAck))
955 {
956 hddLog(VOS_TRACE_LEVEL_ERROR,
957 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530958 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530959 return FALSE;
960 }
961
962 wmmInfo = nla_nest_start(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530964 if(!wmmInfo)
965 {
966 vos_mem_free(pWifiIfaceStatTL);
967 return FALSE;
968 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530969 for (i = 0; i < WIFI_AC_MAX; i++)
970 {
971 struct nlattr *wmmStats;
972 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530973 if(!wmmStats)
974 {
975 vos_mem_free(pWifiIfaceStatTL);
976 return FALSE;
977 }
Sunil Duttc69bccb2014-05-26 21:30:20 +0530978 if (FALSE == put_wifi_wmm_ac_stat(
979 &pWifiIfaceStat->AccessclassStats[i],
980 vendor_event))
981 {
982 hddLog(VOS_TRACE_LEVEL_ERROR,
983 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +0530984 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530985 return FALSE;
986 }
987
988 nla_nest_end(vendor_event, wmmStats);
989 }
990 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +0530991 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +0530992 return TRUE;
993}
994
995static tSirWifiInterfaceMode
996 hdd_map_device_to_ll_iface_mode ( int deviceMode )
997{
998 switch (deviceMode)
999 {
1000 case WLAN_HDD_INFRA_STATION:
1001 return WIFI_INTERFACE_STA;
1002 case WLAN_HDD_SOFTAP:
1003 return WIFI_INTERFACE_SOFTAP;
1004 case WLAN_HDD_P2P_CLIENT:
1005 return WIFI_INTERFACE_P2P_CLIENT;
1006 case WLAN_HDD_P2P_GO:
1007 return WIFI_INTERFACE_P2P_GO;
1008 case WLAN_HDD_IBSS:
1009 return WIFI_INTERFACE_IBSS;
1010 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301011 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301012 }
1013}
1014
1015static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1016 tpSirWifiInterfaceInfo pInfo)
1017{
1018 v_U8_t *staMac = NULL;
1019 hdd_station_ctx_t *pHddStaCtx;
1020 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1021 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1022
1023 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1024
1025 vos_mem_copy(pInfo->macAddr,
1026 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1027
1028 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1029 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1030 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1031 {
1032 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1033 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1034 {
1035 pInfo->state = WIFI_DISCONNECTED;
1036 }
1037 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1038 {
1039 hddLog(VOS_TRACE_LEVEL_ERROR,
1040 "%s: Session ID %d, Connection is in progress", __func__,
1041 pAdapter->sessionId);
1042 pInfo->state = WIFI_ASSOCIATING;
1043 }
1044 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1045 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1046 {
1047 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1048 hddLog(VOS_TRACE_LEVEL_ERROR,
1049 "%s: client " MAC_ADDRESS_STR
1050 " is in the middle of WPS/EAPOL exchange.", __func__,
1051 MAC_ADDR_ARRAY(staMac));
1052 pInfo->state = WIFI_AUTHENTICATING;
1053 }
1054 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1055 {
1056 pInfo->state = WIFI_ASSOCIATED;
1057 vos_mem_copy(pInfo->bssid,
1058 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1059 vos_mem_copy(pInfo->ssid,
1060 pHddStaCtx->conn_info.SSID.SSID.ssId,
1061 pHddStaCtx->conn_info.SSID.SSID.length);
1062 //NULL Terminate the string.
1063 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1064 }
1065 }
1066 vos_mem_copy(pInfo->countryStr,
1067 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1068
1069 vos_mem_copy(pInfo->apCountryStr,
1070 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1071
1072 return TRUE;
1073}
1074
1075/*
1076 * hdd_link_layer_process_peer_stats () - This function is called after
1077 * receiving Link Layer Peer statistics from FW.This function converts
1078 * the firmware data to the NL data and sends the same to the kernel/upper
1079 * layers.
1080 */
1081static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1082 v_VOID_t *pData)
1083{
1084 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1085 tpSirWifiRateStat pWifiRateStat;
1086 tpSirWifiPeerStat pWifiPeerStat;
1087 tpSirWifiPeerInfo pWifiPeerInfo;
1088 struct nlattr *peerInfo;
1089 struct sk_buff *vendor_event;
1090 int status, i;
1091
1092 status = wlan_hdd_validate_context(pHddCtx);
1093 if (0 != status)
1094 {
1095 hddLog(VOS_TRACE_LEVEL_ERROR,
1096 FL("HDD context is not valid") );
1097 return;
1098 }
1099
1100 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1101
1102 hddLog(VOS_TRACE_LEVEL_INFO,
1103 "LL_STATS_PEER_ALL : numPeers %u",
1104 pWifiPeerStat->numPeers);
1105 {
1106 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1107 {
1108 pWifiPeerInfo = (tpSirWifiPeerInfo)
1109 ((uint8 *)pWifiPeerStat->peerInfo +
1110 ( i * sizeof(tSirWifiPeerInfo)));
1111
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301112 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1113 pWifiPeerInfo->type = WIFI_PEER_AP;
1114 }
1115 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1116 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1117 }
1118
Sunil Duttc69bccb2014-05-26 21:30:20 +05301119 hddLog(VOS_TRACE_LEVEL_INFO,
1120 " %d) LL_STATS Channel Stats "
1121 " Peer Type %u "
1122 " peerMacAddress %pM "
1123 " capabilities 0x%x "
1124 " numRate %u ",
1125 i,
1126 pWifiPeerInfo->type,
1127 pWifiPeerInfo->peerMacAddress,
1128 pWifiPeerInfo->capabilities,
1129 pWifiPeerInfo->numRate);
1130 {
1131 int j;
1132 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1133 {
1134 pWifiRateStat = (tpSirWifiRateStat)
1135 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1136 ( j * sizeof(tSirWifiRateStat)));
1137
1138 hddLog(VOS_TRACE_LEVEL_INFO,
1139 " peer Rate Stats "
1140 " preamble %u "
1141 " nss %u "
1142 " bw %u "
1143 " rateMcsIdx %u "
1144 " reserved %u "
1145 " bitrate %u "
1146 " txMpdu %u "
1147 " rxMpdu %u "
1148 " mpduLost %u "
1149 " retries %u "
1150 " retriesShort %u "
1151 " retriesLong %u",
1152 pWifiRateStat->rate.preamble,
1153 pWifiRateStat->rate.nss,
1154 pWifiRateStat->rate.bw,
1155 pWifiRateStat->rate.rateMcsIdx,
1156 pWifiRateStat->rate.reserved,
1157 pWifiRateStat->rate.bitrate,
1158 pWifiRateStat->txMpdu,
1159 pWifiRateStat->rxMpdu,
1160 pWifiRateStat->mpduLost,
1161 pWifiRateStat->retries,
1162 pWifiRateStat->retriesShort,
1163 pWifiRateStat->retriesLong);
1164 }
1165 }
1166 }
1167 }
1168
1169 /*
1170 * Allocate a size of 4096 for the peer stats comprising
1171 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1172 * sizeof (tSirWifiRateStat).Each field is put with an
1173 * NL attribute.The size of 4096 is considered assuming
1174 * that number of rates shall not exceed beyond 50 with
1175 * the sizeof (tSirWifiRateStat) being 32.
1176 */
1177 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1178 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1179 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1180 GFP_KERNEL);
1181 if (!vendor_event)
1182 {
1183 hddLog(VOS_TRACE_LEVEL_ERROR,
1184 "%s: cfg80211_vendor_event_alloc failed",
1185 __func__);
1186 return;
1187 }
1188 if (nla_put_u32(vendor_event,
1189 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1190 pWifiPeerStat->numPeers))
1191 {
1192 hddLog(VOS_TRACE_LEVEL_ERROR,
1193 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1194 kfree_skb(vendor_event);
1195 return;
1196 }
1197
1198 peerInfo = nla_nest_start(vendor_event,
1199 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301200 if(!peerInfo)
1201 {
1202 hddLog(VOS_TRACE_LEVEL_ERROR,
1203 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1204 __func__);
1205 kfree_skb(vendor_event);
1206 return;
1207 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301208
1209 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1210 pWifiPeerStat->peerInfo);
1211
1212 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1213 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301214 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301215 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301216
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301217 if(!peers)
1218 {
1219 hddLog(VOS_TRACE_LEVEL_ERROR,
1220 "%s: peer stats put fail",
1221 __func__);
1222 kfree_skb(vendor_event);
1223 return;
1224 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301225 if (FALSE == put_wifi_peer_info(
1226 pWifiPeerInfo, vendor_event))
1227 {
1228 hddLog(VOS_TRACE_LEVEL_ERROR,
1229 "%s: put_wifi_peer_info put fail", __func__);
1230 kfree_skb(vendor_event);
1231 return;
1232 }
1233
1234 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1235 pWifiPeerStat->peerInfo +
1236 (i * sizeof(tSirWifiPeerInfo)) +
1237 (numRate * sizeof (tSirWifiRateStat)));
1238 nla_nest_end(vendor_event, peers);
1239 }
1240 nla_nest_end(vendor_event, peerInfo);
1241 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1242}
1243
1244/*
1245 * hdd_link_layer_process_iface_stats () - This function is called after
1246 * receiving Link Layer Interface statistics from FW.This function converts
1247 * the firmware data to the NL data and sends the same to the kernel/upper
1248 * layers.
1249 */
1250static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1251 v_VOID_t *pData)
1252{
1253 tpSirWifiIfaceStat pWifiIfaceStat;
1254 struct sk_buff *vendor_event;
1255 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1256 int status;
1257
1258 status = wlan_hdd_validate_context(pHddCtx);
1259 if (0 != status)
1260 {
1261 hddLog(VOS_TRACE_LEVEL_ERROR,
1262 FL("HDD context is not valid") );
1263 return;
1264 }
1265 /*
1266 * Allocate a size of 4096 for the interface stats comprising
1267 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1268 * assuming that all these fit with in the limit.Please take
1269 * a call on the limit based on the data requirements on
1270 * interface statistics.
1271 */
1272 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1273 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1274 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1275 GFP_KERNEL);
1276 if (!vendor_event)
1277 {
1278 hddLog(VOS_TRACE_LEVEL_ERROR,
1279 FL("cfg80211_vendor_event_alloc failed") );
1280 return;
1281 }
1282
1283 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1284
Dino Mycle3b9536d2014-07-09 22:05:24 +05301285
1286 if (FALSE == hdd_get_interface_info( pAdapter,
1287 &pWifiIfaceStat->info))
1288 {
1289 hddLog(VOS_TRACE_LEVEL_ERROR,
1290 FL("hdd_get_interface_info get fail") );
1291 kfree_skb(vendor_event);
1292 return;
1293 }
1294
1295 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1296 vendor_event))
1297 {
1298 hddLog(VOS_TRACE_LEVEL_ERROR,
1299 FL("put_wifi_iface_stats fail") );
1300 kfree_skb(vendor_event);
1301 return;
1302 }
1303
Sunil Duttc69bccb2014-05-26 21:30:20 +05301304 hddLog(VOS_TRACE_LEVEL_INFO,
1305 "WMI_LINK_STATS_IFACE Data");
1306
1307 hddLog(VOS_TRACE_LEVEL_INFO,
1308 "LL_STATS_IFACE: "
1309 " Mode %u "
1310 " MAC %pM "
1311 " State %u "
1312 " Roaming %u "
1313 " capabilities 0x%x "
1314 " SSID %s "
1315 " BSSID %pM",
1316 pWifiIfaceStat->info.mode,
1317 pWifiIfaceStat->info.macAddr,
1318 pWifiIfaceStat->info.state,
1319 pWifiIfaceStat->info.roaming,
1320 pWifiIfaceStat->info.capabilities,
1321 pWifiIfaceStat->info.ssid,
1322 pWifiIfaceStat->info.bssid);
1323
1324 hddLog(VOS_TRACE_LEVEL_INFO,
1325 " AP country str: %c%c%c",
1326 pWifiIfaceStat->info.apCountryStr[0],
1327 pWifiIfaceStat->info.apCountryStr[1],
1328 pWifiIfaceStat->info.apCountryStr[2]);
1329
1330
1331 hddLog(VOS_TRACE_LEVEL_INFO,
1332 " Country Str Association: %c%c%c",
1333 pWifiIfaceStat->info.countryStr[0],
1334 pWifiIfaceStat->info.countryStr[1],
1335 pWifiIfaceStat->info.countryStr[2]);
1336
1337 hddLog(VOS_TRACE_LEVEL_INFO,
1338 " beaconRx %u "
1339 " mgmtRx %u "
1340 " mgmtActionRx %u "
1341 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301342 " rssiMgmt %d "
1343 " rssiData %d "
1344 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 pWifiIfaceStat->beaconRx,
1346 pWifiIfaceStat->mgmtRx,
1347 pWifiIfaceStat->mgmtActionRx,
1348 pWifiIfaceStat->mgmtActionTx,
1349 pWifiIfaceStat->rssiMgmt,
1350 pWifiIfaceStat->rssiData,
1351 pWifiIfaceStat->rssiAck );
1352
1353
1354 {
1355 int i;
1356 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1357 {
1358 hddLog(VOS_TRACE_LEVEL_INFO,
1359
1360 " %d) LL_STATS IFACE: "
1361 " ac: %u txMpdu: %u "
1362 " rxMpdu: %u txMcast: %u "
1363 " rxMcast: %u rxAmpdu: %u "
1364 " txAmpdu: %u mpduLost: %u "
1365 " retries: %u retriesShort: %u "
1366 " retriesLong: %u contentionTimeMin: %u "
1367 " contentionTimeMax: %u contentionTimeAvg: %u "
1368 " contentionNumSamples: %u",
1369 i,
1370 pWifiIfaceStat->AccessclassStats[i].ac,
1371 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1372 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1373 pWifiIfaceStat->AccessclassStats[i].txMcast,
1374 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1375 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1376 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1377 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1378 pWifiIfaceStat->AccessclassStats[i].retries,
1379 pWifiIfaceStat->
1380 AccessclassStats[i].retriesShort,
1381 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1382 pWifiIfaceStat->
1383 AccessclassStats[i].contentionTimeMin,
1384 pWifiIfaceStat->
1385 AccessclassStats[i].contentionTimeMax,
1386 pWifiIfaceStat->
1387 AccessclassStats[i].contentionTimeAvg,
1388 pWifiIfaceStat->
1389 AccessclassStats[i].contentionNumSamples);
1390
1391 }
1392 }
1393
Sunil Duttc69bccb2014-05-26 21:30:20 +05301394 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1395}
1396
1397/*
1398 * hdd_link_layer_process_radio_stats () - This function is called after
1399 * receiving Link Layer Radio statistics from FW.This function converts
1400 * the firmware data to the NL data and sends the same to the kernel/upper
1401 * layers.
1402 */
1403static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1404 v_VOID_t *pData)
1405{
1406 int status, i;
1407 tpSirWifiRadioStat pWifiRadioStat;
1408 tpSirWifiChannelStats pWifiChannelStats;
1409 struct sk_buff *vendor_event;
1410 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1411 struct nlattr *chList;
1412
1413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
1416 hddLog(VOS_TRACE_LEVEL_ERROR,
1417 FL("HDD context is not valid") );
1418 return;
1419 }
1420 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1421
1422 hddLog(VOS_TRACE_LEVEL_INFO,
1423 "LL_STATS_RADIO"
1424 " radio is %d onTime is %u "
1425 " txTime is %u rxTime is %u "
1426 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301427 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301428 " onTimePnoScan is %u onTimeHs20 is %u "
1429 " numChannels is %u",
1430 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1431 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1432 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301433 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301434 pWifiRadioStat->onTimeRoamScan,
1435 pWifiRadioStat->onTimePnoScan,
1436 pWifiRadioStat->onTimeHs20,
1437 pWifiRadioStat->numChannels);
1438 /*
1439 * Allocate a size of 4096 for the Radio stats comprising
1440 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1441 * (tSirWifiChannelStats).Each channel data is put with an
1442 * NL attribute.The size of 4096 is considered assuming that
1443 * number of channels shall not exceed beyond 60 with the
1444 * sizeof (tSirWifiChannelStats) being 24 bytes.
1445 */
1446
1447 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1448 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1449 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1450 GFP_KERNEL);
1451
1452 if (!vendor_event)
1453 {
1454 hddLog(VOS_TRACE_LEVEL_ERROR,
1455 FL("cfg80211_vendor_event_alloc failed") );
1456 return;
1457 }
1458
1459 if (nla_put_u32(vendor_event,
1460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1461 pWifiRadioStat->radio) ||
1462 nla_put_u32(vendor_event,
1463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1464 pWifiRadioStat->onTime) ||
1465 nla_put_u32(vendor_event,
1466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1467 pWifiRadioStat->txTime) ||
1468 nla_put_u32(vendor_event,
1469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1470 pWifiRadioStat->rxTime) ||
1471 nla_put_u32(vendor_event,
1472 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1473 pWifiRadioStat->onTimeScan) ||
1474 nla_put_u32(vendor_event,
1475 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1476 pWifiRadioStat->onTimeNbd) ||
1477 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301478 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1479 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301480 nla_put_u32(vendor_event,
1481 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1482 pWifiRadioStat->onTimeRoamScan) ||
1483 nla_put_u32(vendor_event,
1484 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1485 pWifiRadioStat->onTimePnoScan) ||
1486 nla_put_u32(vendor_event,
1487 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1488 pWifiRadioStat->onTimeHs20) ||
1489 nla_put_u32(vendor_event,
1490 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1491 pWifiRadioStat->numChannels))
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
1494 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1495 kfree_skb(vendor_event);
1496 return ;
1497 }
1498
1499 chList = nla_nest_start(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301501 if(!chList)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_ERROR,
1504 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1505 __func__);
1506 kfree_skb(vendor_event);
1507 return;
1508 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301509 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1510 {
1511 struct nlattr *chInfo;
1512
1513 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1514 pWifiRadioStat->channels +
1515 (i * sizeof(tSirWifiChannelStats)));
1516
1517 hddLog(VOS_TRACE_LEVEL_INFO,
1518 " %d) Channel Info"
1519 " width is %u "
1520 " CenterFreq %u "
1521 " CenterFreq0 %u "
1522 " CenterFreq1 %u "
1523 " onTime %u "
1524 " ccaBusyTime %u",
1525 i,
1526 pWifiChannelStats->channel.width,
1527 pWifiChannelStats->channel.centerFreq,
1528 pWifiChannelStats->channel.centerFreq0,
1529 pWifiChannelStats->channel.centerFreq1,
1530 pWifiChannelStats->onTime,
1531 pWifiChannelStats->ccaBusyTime);
1532
1533
1534 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301535 if(!chInfo)
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR,
1538 "%s: failed to put chInfo",
1539 __func__);
1540 kfree_skb(vendor_event);
1541 return;
1542 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301543
1544 if (nla_put_u32(vendor_event,
1545 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1546 pWifiChannelStats->channel.width) ||
1547 nla_put_u32(vendor_event,
1548 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1549 pWifiChannelStats->channel.centerFreq) ||
1550 nla_put_u32(vendor_event,
1551 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1552 pWifiChannelStats->channel.centerFreq0) ||
1553 nla_put_u32(vendor_event,
1554 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1555 pWifiChannelStats->channel.centerFreq1) ||
1556 nla_put_u32(vendor_event,
1557 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1558 pWifiChannelStats->onTime) ||
1559 nla_put_u32(vendor_event,
1560 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1561 pWifiChannelStats->ccaBusyTime))
1562 {
1563 hddLog(VOS_TRACE_LEVEL_ERROR,
1564 FL("cfg80211_vendor_event_alloc failed") );
1565 kfree_skb(vendor_event);
1566 return ;
1567 }
1568 nla_nest_end(vendor_event, chInfo);
1569 }
1570 nla_nest_end(vendor_event, chList);
1571
1572 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1573 return;
1574}
1575
1576/*
1577 * hdd_link_layer_stats_ind_callback () - This function is called after
1578 * receiving Link Layer indications from FW.This callback converts the firmware
1579 * data to the NL data and send the same to the kernel/upper layers.
1580 */
1581static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1582 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584{
Dino Mycled3d50022014-07-07 12:58:25 +05301585 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1586 hdd_adapter_t *pAdapter = NULL;
1587 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 int status;
1589
1590 status = wlan_hdd_validate_context(pHddCtx);
1591
1592 if (0 != status)
1593 {
1594 hddLog(VOS_TRACE_LEVEL_ERROR,
1595 FL("HDD context is not valid"));
1596 return;
1597 }
1598
Dino Mycled3d50022014-07-07 12:58:25 +05301599
1600
1601 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1602 if (NULL == pAdapter)
1603 {
1604 hddLog(VOS_TRACE_LEVEL_ERROR,
1605 FL(" MAC address %pM does not exist with host"),
1606 macAddr);
1607 return;
1608 }
1609
Sunil Duttc69bccb2014-05-26 21:30:20 +05301610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301611 "%s: Interface: %s LLStats indType: %d", __func__,
1612 pAdapter->dev->name, indType);
1613
Sunil Duttc69bccb2014-05-26 21:30:20 +05301614 switch (indType)
1615 {
1616 case SIR_HAL_LL_STATS_RESULTS_RSP:
1617 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301618 hddLog(VOS_TRACE_LEVEL_INFO,
1619 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1620 hddLog(VOS_TRACE_LEVEL_INFO,
1621 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1622 linkLayerStatsResults->paramId);
1623 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301624 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1625 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301626 hddLog(VOS_TRACE_LEVEL_INFO,
1627 "LL_STATS RESULTS RESPONSE respId = %u",
1628 linkLayerStatsResults->respId);
1629 hddLog(VOS_TRACE_LEVEL_INFO,
1630 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1631 linkLayerStatsResults->moreResultToFollow);
1632 hddLog(VOS_TRACE_LEVEL_INFO,
1633 "LL_STATS RESULTS RESPONSE result = %p",
1634 linkLayerStatsResults->result);
1635 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1636 {
1637 hdd_link_layer_process_radio_stats(pAdapter,
1638 (v_VOID_t *)linkLayerStatsResults->result);
1639 }
1640 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1641 {
1642 hdd_link_layer_process_iface_stats(pAdapter,
1643 (v_VOID_t *)linkLayerStatsResults->result);
1644 }
1645 else if ( linkLayerStatsResults->paramId &
1646 WMI_LINK_STATS_ALL_PEER )
1647 {
1648 hdd_link_layer_process_peer_stats(pAdapter,
1649 (v_VOID_t *)linkLayerStatsResults->result);
1650 } /* WMI_LINK_STATS_ALL_PEER */
1651 else
1652 {
1653 hddLog(VOS_TRACE_LEVEL_ERROR,
1654 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1655 }
1656
1657 break;
1658 }
1659 default:
1660 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1661 break;
1662 }
1663 return;
1664}
1665
1666const struct
1667nla_policy
1668qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1669{
1670 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1671 { .type = NLA_U32 },
1672 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1673 { .type = NLA_U32 },
1674};
1675
1676static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1677 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301678 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301679 int data_len)
1680{
1681 int status;
1682 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301683 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684 struct net_device *dev = wdev->netdev;
1685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301687 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688
1689 status = wlan_hdd_validate_context(pHddCtx);
1690 if (0 != status)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 FL("HDD context is not valid"));
1694 return -EINVAL;
1695 }
1696
1697 if (NULL == pAdapter)
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 FL("HDD adapter is Null"));
1701 return -ENODEV;
1702 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 /* check the LLStats Capability */
1704 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1705 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1706 {
1707 hddLog(VOS_TRACE_LEVEL_ERROR,
1708 FL("Link Layer Statistics not supported by Firmware"));
1709 return -EINVAL;
1710 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711
1712 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1713 (struct nlattr *)data,
1714 data_len, qca_wlan_vendor_ll_set_policy))
1715 {
1716 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1717 return -EINVAL;
1718 }
1719 if (!tb_vendor
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1723 return -EINVAL;
1724 }
1725 if (!tb_vendor[
1726 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1729 return -EINVAL;
1730 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301731 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 nla_get_u32(
1736 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1737
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 nla_get_u32(
1740 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1741
Dino Mycled3d50022014-07-07 12:58:25 +05301742 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1743 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745
1746 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301747 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301749 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 hddLog(VOS_TRACE_LEVEL_INFO,
1751 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301752 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301753 hddLog(VOS_TRACE_LEVEL_INFO,
1754 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301755 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756
1757 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1758 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301759 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1762 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301763 return -EINVAL;
1764
1765 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301766
1767 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1768 if (VOS_STATUS_SUCCESS !=
1769 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1770 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1771 {
1772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1773 "WLANTL_ClearInterfaceStats Failed", __func__);
1774 return -EINVAL;
1775 }
1776
1777 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
1778 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
1779 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
1780 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
1781
Sunil Duttc69bccb2014-05-26 21:30:20 +05301782 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301783 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301784 {
1785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1786 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301787 return -EINVAL;
1788 }
1789
1790 pAdapter->isLinkLayerStatsSet = 1;
1791
1792 return 0;
1793}
1794
1795const struct
1796nla_policy
1797qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1798{
1799 /* Unsigned 32bit value provided by the caller issuing the GET stats
1800 * command. When reporting
1801 * the stats results, the driver uses the same value to indicate
1802 * which GET request the results
1803 * correspond to.
1804 */
1805 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1806
1807 /* Unsigned 32bit value . bit mask to identify what statistics are
1808 requested for retrieval */
1809 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1810};
1811
1812static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301814 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301815 int data_len)
1816{
1817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1822 int status;
1823
1824 status = wlan_hdd_validate_context(pHddCtx);
1825 if (0 != status)
1826 {
1827 hddLog(VOS_TRACE_LEVEL_ERROR,
1828 FL("HDD context is not valid"));
1829 return -EINVAL ;
1830 }
1831
1832 if (NULL == pAdapter)
1833 {
1834 hddLog(VOS_TRACE_LEVEL_FATAL,
1835 "%s: HDD adapter is Null", __func__);
1836 return -ENODEV;
1837 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301838 /* check the LLStats Capability */
1839 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1840 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1841 {
1842 hddLog(VOS_TRACE_LEVEL_ERROR,
1843 FL("Link Layer Statistics not supported by Firmware"));
1844 return -EINVAL;
1845 }
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847
1848 if (!pAdapter->isLinkLayerStatsSet)
1849 {
1850 hddLog(VOS_TRACE_LEVEL_FATAL,
1851 "%s: isLinkLayerStatsSet : %d",
1852 __func__, pAdapter->isLinkLayerStatsSet);
1853 return -EINVAL;
1854 }
1855
1856 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1857 (struct nlattr *)data,
1858 data_len, qca_wlan_vendor_ll_get_policy))
1859 {
1860 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1861 return -EINVAL;
1862 }
1863
1864 if (!tb_vendor
1865 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1866 {
1867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1868 return -EINVAL;
1869 }
1870
1871 if (!tb_vendor
1872 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1873 {
1874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1875 return -EINVAL;
1876 }
1877
Sunil Duttc69bccb2014-05-26 21:30:20 +05301878
Dino Mycledf0a5d92014-07-04 09:41:55 +05301879 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301880 nla_get_u32( tb_vendor[
1881 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301883 nla_get_u32( tb_vendor[
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1885
Dino Mycled3d50022014-07-07 12:58:25 +05301886 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1887 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301888
1889 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301892 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 hddLog(VOS_TRACE_LEVEL_INFO,
1894 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896
1897 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 {
1900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1901 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 return -EINVAL;
1903 }
1904 return 0;
1905}
1906
1907const struct
1908nla_policy
1909qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1910{
1911 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1912 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1913 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1914 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1915};
1916
1917static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1918 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05301919 const void *data,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920 int data_len)
1921{
1922 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1923 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301924 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301925 struct net_device *dev = wdev->netdev;
1926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1927 u32 statsClearReqMask;
1928 u8 stopReq;
1929 int status;
1930
1931 status = wlan_hdd_validate_context(pHddCtx);
1932 if (0 != status)
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR,
1935 FL("HDD context is not valid"));
1936 return -EINVAL;
1937 }
1938
1939 if (NULL == pAdapter)
1940 {
1941 hddLog(VOS_TRACE_LEVEL_FATAL,
1942 "%s: HDD adapter is Null", __func__);
1943 return -ENODEV;
1944 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301945 /* check the LLStats Capability */
1946 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1947 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR,
1950 FL("Enable LLStats Capability"));
1951 return -EINVAL;
1952 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953
1954 if (!pAdapter->isLinkLayerStatsSet)
1955 {
1956 hddLog(VOS_TRACE_LEVEL_FATAL,
1957 "%s: isLinkLayerStatsSet : %d",
1958 __func__, pAdapter->isLinkLayerStatsSet);
1959 return -EINVAL;
1960 }
1961
1962 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1963 (struct nlattr *)data,
1964 data_len, qca_wlan_vendor_ll_clr_policy))
1965 {
1966 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1967 return -EINVAL;
1968 }
1969
1970 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1971
1972 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1973 {
1974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1975 return -EINVAL;
1976
1977 }
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979
Dino Mycledf0a5d92014-07-04 09:41:55 +05301980 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981 nla_get_u32(
1982 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1983
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 nla_get_u8(
1986 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1987
1988 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301989 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301990
Dino Mycled3d50022014-07-07 12:58:25 +05301991 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1992 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301993
1994 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301995 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301996 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301997 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998 hddLog(VOS_TRACE_LEVEL_INFO,
1999 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302000 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302001 hddLog(VOS_TRACE_LEVEL_INFO,
2002 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302004
2005 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302006 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 {
2008 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302009 hdd_station_ctx_t *pHddStaCtx;
2010
2011 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2012 if (VOS_STATUS_SUCCESS !=
2013 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2014 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2015 {
2016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2017 "WLANTL_ClearInterfaceStats Failed", __func__);
2018 return -EINVAL;
2019 }
2020 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2021 (statsClearReqMask & WIFI_STATS_IFACE)) {
2022 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2023 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2024 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2025 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2026 }
2027
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2029 2 * sizeof(u32) +
2030 NLMSG_HDRLEN);
2031
2032 if (temp_skbuff != NULL)
2033 {
2034
2035 if (nla_put_u32(temp_skbuff,
2036 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2037 statsClearReqMask) ||
2038 nla_put_u32(temp_skbuff,
2039 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2040 stopReq))
2041 {
2042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2043 kfree_skb(temp_skbuff);
2044 return -EINVAL;
2045 }
2046 /* If the ask is to stop the stats collection as part of clear
2047 * (stopReq = 1) , ensure that no further requests of get
2048 * go to the firmware by having isLinkLayerStatsSet set to 0.
2049 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302050 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302051 * case the firmware is just asked to clear the statistics.
2052 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302053 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302054 pAdapter->isLinkLayerStatsSet = 0;
2055 return cfg80211_vendor_cmd_reply(temp_skbuff);
2056 }
2057 return -ENOMEM;
2058 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059 return -EINVAL;
2060}
2061#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2062
Dino Mycle6fb96c12014-06-10 11:52:40 +05302063#ifdef WLAN_FEATURE_EXTSCAN
2064static const struct nla_policy
2065wlan_hdd_extscan_config_policy
2066 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2067{
2068 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2069 { .type = NLA_U32 },
2070 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2071 { .type = NLA_U32 },
2072 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2073 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2074 { .type = NLA_U32 },
2075 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2076 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2077
2078 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2079 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2080 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2081 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2082 { .type = NLA_U8 },
2083 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2084 { .type = NLA_U32 },
2085 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2086 { .type = NLA_U32 },
2087 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2088 { .type = NLA_U32 },
2089 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2090 { .type = NLA_U8 },
2091 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2092 { .type = NLA_U8 },
2093 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2094 { .type = NLA_U8 },
2095
2096 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2097 { .type = NLA_U32 },
2098 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2099 { .type = NLA_UNSPEC },
2100 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2101 { .type = NLA_S32 },
2102 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2103 { .type = NLA_S32 },
2104 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2105 { .type = NLA_U32 },
2106 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2107 { .type = NLA_U32 },
2108 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2109 { .type = NLA_U32 },
2110 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2111 = { .type = NLA_U32 },
2112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2113 { .type = NLA_U32 },
2114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2115 NLA_U32 },
2116};
2117
2118static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2119{
2120 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2121 struct sk_buff *skb = NULL;
2122 tpSirEXTScanCapabilitiesEvent pData =
2123 (tpSirEXTScanCapabilitiesEvent) pMsg;
2124
2125 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2127 "or pData(%p) is null"), pData);
2128 return;
2129 }
2130
2131 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2132 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2133 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2134 GFP_KERNEL);
2135
2136 if (!skb) {
2137 hddLog(VOS_TRACE_LEVEL_ERROR,
2138 FL("cfg80211_vendor_event_alloc failed"));
2139 return;
2140 }
2141
2142 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2143 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2144 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2145 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2146 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2147 pData->maxRssiSampleSize);
2148 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2149 pData->maxScanReportingThreshold);
2150 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2151 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2152 pData->maxSignificantWifiChangeAPs);
2153 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2154 pData->maxBsidHistoryEntries);
2155
2156 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2157 pData->requestId) ||
2158 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2159 nla_put_u32(skb,
2160 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2161 pData->scanCacheSize) ||
2162 nla_put_u32(skb,
2163 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2164 pData->scanBuckets) ||
2165 nla_put_u32(skb,
2166 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2167 pData->maxApPerScan) ||
2168 nla_put_u32(skb,
2169 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2170 pData->maxRssiSampleSize) ||
2171 nla_put_u32(skb,
2172 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2173 pData->maxScanReportingThreshold) ||
2174 nla_put_u32(skb,
2175 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2176 pData->maxHotlistAPs) ||
2177 nla_put_u32(skb,
2178 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2179 pData->maxSignificantWifiChangeAPs) ||
2180 nla_put_u32(skb,
2181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2182 pData->maxBsidHistoryEntries)) {
2183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2184 goto nla_put_failure;
2185 }
2186
2187 cfg80211_vendor_event(skb, GFP_KERNEL);
2188 return;
2189
2190nla_put_failure:
2191 kfree_skb(skb);
2192 return;
2193}
2194
2195
2196static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2197{
2198 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2199 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2200 struct sk_buff *skb = NULL;
2201 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2202
2203
2204 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2206 "or pData(%p) is null"), pData);
2207 return;
2208 }
2209
2210 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2211 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2212 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2213 GFP_KERNEL);
2214
2215 if (!skb) {
2216 hddLog(VOS_TRACE_LEVEL_ERROR,
2217 FL("cfg80211_vendor_event_alloc failed"));
2218 return;
2219 }
2220 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2221 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2222 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2223
2224 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2225 pData->requestId) ||
2226 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2228 goto nla_put_failure;
2229 }
2230
2231 /*
2232 * Store the Request ID for comparing with the requestID obtained
2233 * in other requests.HDD shall return a failure is the extscan_stop
2234 * request is issued with a different requestId as that of the
2235 * extscan_start request. Also, This requestId shall be used while
2236 * indicating the full scan results to the upper layers.
2237 * The requestId is stored with the assumption that the firmware
2238 * shall return the ext scan start request's requestId in ext scan
2239 * start response.
2240 */
2241 if (pData->status == 0)
2242 pMac->sme.extScanStartReqId = pData->requestId;
2243
2244
2245 cfg80211_vendor_event(skb, GFP_KERNEL);
2246 return;
2247
2248nla_put_failure:
2249 kfree_skb(skb);
2250 return;
2251}
2252
2253
2254static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2255{
2256 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2257 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2258 struct sk_buff *skb = NULL;
2259
2260 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2262 "or pData(%p) is null"), pData);
2263 return;
2264 }
2265
2266 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2267 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2268 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2269 GFP_KERNEL);
2270
2271 if (!skb) {
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 FL("cfg80211_vendor_event_alloc failed"));
2274 return;
2275 }
2276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2277 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2278
2279 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2280 pData->requestId) ||
2281 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2283 goto nla_put_failure;
2284 }
2285
2286 cfg80211_vendor_event(skb, GFP_KERNEL);
2287 return;
2288
2289nla_put_failure:
2290 kfree_skb(skb);
2291 return;
2292}
2293
2294
2295static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2296 void *pMsg)
2297{
2298 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2299 struct sk_buff *skb = NULL;
2300 tpSirEXTScanSetBssidHotListRspParams pData =
2301 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2302
2303 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2305 "or pData(%p) is null"), pData);
2306 return;
2307 }
2308 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2309 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2310 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2311 GFP_KERNEL);
2312
2313 if (!skb) {
2314 hddLog(VOS_TRACE_LEVEL_ERROR,
2315 FL("cfg80211_vendor_event_alloc failed"));
2316 return;
2317 }
2318 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2319 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2320 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2321
2322 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2323 pData->requestId) ||
2324 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2326 goto nla_put_failure;
2327 }
2328
2329 cfg80211_vendor_event(skb, GFP_KERNEL);
2330 return;
2331
2332nla_put_failure:
2333 kfree_skb(skb);
2334 return;
2335}
2336
2337static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2338 void *pMsg)
2339{
2340 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2341 struct sk_buff *skb = NULL;
2342 tpSirEXTScanResetBssidHotlistRspParams pData =
2343 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2344
2345 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2347 "or pData(%p) is null"), pData);
2348 return;
2349 }
2350
2351 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2352 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2353 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2354 GFP_KERNEL);
2355
2356 if (!skb) {
2357 hddLog(VOS_TRACE_LEVEL_ERROR,
2358 FL("cfg80211_vendor_event_alloc failed"));
2359 return;
2360 }
2361 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2362 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2363
2364 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2365 pData->requestId) ||
2366 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2368 goto nla_put_failure;
2369 }
2370
2371 cfg80211_vendor_event(skb, GFP_KERNEL);
2372 return;
2373
2374nla_put_failure:
2375 kfree_skb(skb);
2376 return;
2377}
2378
2379
2380static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2381 void *pMsg)
2382{
2383 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2384 struct sk_buff *skb = NULL;
2385 tpSirEXTScanSetSignificantChangeRspParams pData =
2386 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2387
2388 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2389 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2390 "or pData(%p) is null"), pData);
2391 return;
2392 }
2393
2394 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2395 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2396 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2397 GFP_KERNEL);
2398
2399 if (!skb) {
2400 hddLog(VOS_TRACE_LEVEL_ERROR,
2401 FL("cfg80211_vendor_event_alloc failed"));
2402 return;
2403 }
2404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2405 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2406 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2407
2408 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2409 pData->requestId) ||
2410 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2412 goto nla_put_failure;
2413 }
2414
2415 cfg80211_vendor_event(skb, GFP_KERNEL);
2416 return;
2417
2418nla_put_failure:
2419 kfree_skb(skb);
2420 return;
2421}
2422
2423
2424static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2425 void *pMsg)
2426{
2427 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2428 struct sk_buff *skb = NULL;
2429 tpSirEXTScanResetSignificantChangeRspParams pData =
2430 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2431
2432 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2434 "or pData(%p) is null"), pData);
2435 return;
2436 }
2437
2438 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2439 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2440 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2441 GFP_KERNEL);
2442
2443 if (!skb) {
2444 hddLog(VOS_TRACE_LEVEL_ERROR,
2445 FL("cfg80211_vendor_event_alloc failed"));
2446 return;
2447 }
2448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2449 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2450 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2451
2452 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2453 pData->requestId) ||
2454 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2456 goto nla_put_failure;
2457 }
2458
2459 cfg80211_vendor_event(skb, GFP_KERNEL);
2460 return;
2461
2462nla_put_failure:
2463 kfree_skb(skb);
2464 return;
2465}
2466
2467static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2468 void *pMsg)
2469{
2470 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2471 struct sk_buff *skb = NULL;
2472 tANI_U32 i = 0, j, resultsPerEvent;
2473 tANI_S32 totalResults;
2474 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2475 tpSirWifiScanResult pSirWifiScanResult;
2476
2477 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2479 "or pData(%p) is null"), pData);
2480 return;
2481 }
2482 totalResults = pData->numOfAps;
2483 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2484 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2485 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2486
2487 do{
2488 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2489 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2490 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2491
2492 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2493 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2494 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2495 GFP_KERNEL);
2496
2497 if (!skb) {
2498 hddLog(VOS_TRACE_LEVEL_ERROR,
2499 FL("cfg80211_vendor_event_alloc failed"));
2500 return;
2501 }
2502
2503 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2504
2505 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2506 pData->requestId) ||
2507 nla_put_u32(skb,
2508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2509 resultsPerEvent)) {
2510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2511 goto fail;
2512 }
2513 if (nla_put_u8(skb,
2514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2515 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2516 {
2517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2518 goto fail;
2519 }
2520
2521 if (resultsPerEvent) {
2522 struct nlattr *aps;
2523
2524 aps = nla_nest_start(skb,
2525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2526 if (!aps)
2527 {
2528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2529 goto fail;
2530 }
2531
2532 for (j = 0; j < resultsPerEvent; j++, i++) {
2533 struct nlattr *ap;
2534 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2535 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2536
2537 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2538 "Ssid (%s)"
2539 "Bssid: %pM "
2540 "Channel (%u)"
2541 "Rssi (%d)"
2542 "RTT (%u)"
2543 "RTT_SD (%u)",
2544 i,
2545 pSirWifiScanResult->ts,
2546 pSirWifiScanResult->ssid,
2547 pSirWifiScanResult->bssid,
2548 pSirWifiScanResult->channel,
2549 pSirWifiScanResult->rssi,
2550 pSirWifiScanResult->rtt,
2551 pSirWifiScanResult->rtt_sd);
2552
2553 ap = nla_nest_start(skb, j + 1);
2554 if (!ap)
2555 {
2556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2557 goto fail;
2558 }
2559
2560 if (nla_put_u64(skb,
2561 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2562 pSirWifiScanResult->ts) )
2563 {
2564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2565 goto fail;
2566 }
2567 if (nla_put(skb,
2568 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2569 sizeof(pSirWifiScanResult->ssid),
2570 pSirWifiScanResult->ssid) )
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2573 goto fail;
2574 }
2575 if (nla_put(skb,
2576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2577 sizeof(pSirWifiScanResult->bssid),
2578 pSirWifiScanResult->bssid) )
2579 {
2580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2581 goto fail;
2582 }
2583 if (nla_put_u32(skb,
2584 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2585 pSirWifiScanResult->channel) )
2586 {
2587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2588 goto fail;
2589 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302590 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2592 pSirWifiScanResult->rssi) )
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2595 goto fail;
2596 }
2597 if (nla_put_u32(skb,
2598 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2599 pSirWifiScanResult->rtt) )
2600 {
2601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2602 goto fail;
2603 }
2604 if (nla_put_u32(skb,
2605 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2606 pSirWifiScanResult->rtt_sd))
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2609 goto fail;
2610 }
2611
2612 nla_nest_end(skb, ap);
2613 }
2614 nla_nest_end(skb, aps);
2615
2616 }
2617 cfg80211_vendor_event(skb, GFP_KERNEL);
2618 } while (totalResults > 0);
2619
2620 return;
2621fail:
2622 kfree_skb(skb);
2623 return;
2624}
2625
2626static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2627 void *pMsg)
2628{
2629 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2630 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2631 struct sk_buff *skb = NULL;
2632 tANI_U32 i;
2633
2634 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2636 "or pData(%p) is null"), pData);
2637 return;
2638 }
2639
2640 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2641 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2642 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2643 GFP_KERNEL);
2644
2645 if (!skb) {
2646 hddLog(VOS_TRACE_LEVEL_ERROR,
2647 FL("cfg80211_vendor_event_alloc failed"));
2648 return;
2649 }
2650 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2651 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2652 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2653 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2654
2655 for (i = 0; i < pData->numOfAps; i++) {
2656 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2657 "Ssid (%s) "
2658 "Bssid (" MAC_ADDRESS_STR ") "
2659 "Channel (%u) "
2660 "Rssi (%d) "
2661 "RTT (%u) "
2662 "RTT_SD (%u) ",
2663 i,
2664 pData->ap[i].ts,
2665 pData->ap[i].ssid,
2666 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2667 pData->ap[i].channel,
2668 pData->ap[i].rssi,
2669 pData->ap[i].rtt,
2670 pData->ap[i].rtt_sd);
2671 }
2672
2673 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2674 pData->requestId) ||
2675 nla_put_u32(skb,
2676 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2677 pData->numOfAps)) {
2678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2679 goto fail;
2680 }
2681 if (pData->numOfAps) {
2682 struct nlattr *aps;
2683
2684 aps = nla_nest_start(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2686 if (!aps)
2687 goto fail;
2688
2689 for (i = 0; i < pData->numOfAps; i++) {
2690 struct nlattr *ap;
2691
2692 ap = nla_nest_start(skb, i + 1);
2693 if (!ap)
2694 goto fail;
2695
2696 if (nla_put_u64(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2698 pData->ap[i].ts) ||
2699 nla_put(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2701 sizeof(pData->ap[i].ssid),
2702 pData->ap[i].ssid) ||
2703 nla_put(skb,
2704 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2705 sizeof(pData->ap[i].bssid),
2706 pData->ap[i].bssid) ||
2707 nla_put_u32(skb,
2708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2709 pData->ap[i].channel) ||
2710 nla_put_s32(skb,
2711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2712 pData->ap[i].rssi) ||
2713 nla_put_u32(skb,
2714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2715 pData->ap[i].rtt) ||
2716 nla_put_u32(skb,
2717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2718 pData->ap[i].rtt_sd))
2719 goto fail;
2720
2721 nla_nest_end(skb, ap);
2722 }
2723 nla_nest_end(skb, aps);
2724
2725 if (nla_put_u8(skb,
2726 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2727 pData->moreData))
2728 goto fail;
2729 }
2730
2731 cfg80211_vendor_event(skb, GFP_KERNEL);
2732 return;
2733
2734fail:
2735 kfree_skb(skb);
2736 return;
2737
2738}
2739static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2740 void *pMsg)
2741{
2742 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2743 struct sk_buff *skb = NULL;
2744 tANI_U32 i, j;
2745 tpSirWifiSignificantChangeEvent pData =
2746 (tpSirWifiSignificantChangeEvent) pMsg;
2747
2748 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2750 "or pData(%p) is null"), pData);
2751 return;
2752 }
2753 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2754 EXTSCAN_EVENT_BUF_SIZE,
2755 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2756 GFP_KERNEL);
2757
2758 if (!skb) {
2759 hddLog(VOS_TRACE_LEVEL_ERROR,
2760 FL("cfg80211_vendor_event_alloc failed"));
2761 return;
2762 }
2763 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2764 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2765 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2766 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2767 pData->numSigRssiBss);
2768 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2769
2770 for (i = 0; i < pData->numSigRssiBss; i++) {
2771 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2772 " num RSSI %u ",
2773 i, pData->sigRssiResult[i].bssid,
2774 pData->sigRssiResult[i].channel,
2775 pData->sigRssiResult[i].numRssi);
2776
2777 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2778
2779 hddLog(VOS_TRACE_LEVEL_INFO,
2780 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05302781 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302782
2783 }
2784 }
2785
2786
2787 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2788 pData->requestId) ||
2789 nla_put_u32(skb,
2790 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2791 pData->numSigRssiBss)) {
2792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2793 goto fail;
2794 }
2795
2796 if (pData->numSigRssiBss) {
2797 struct nlattr *aps;
2798 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2799 if (!aps)
2800 goto fail;
2801 for (i = 0; i < pData->numSigRssiBss; i++) {
2802 struct nlattr *ap;
2803
2804 ap = nla_nest_start(skb, i);
2805 if (!ap)
2806 goto fail;
2807 if (nla_put(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2809 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2810 nla_put_u32(skb,
2811 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2812 pData->sigRssiResult[i].channel) ||
2813 nla_put_u32(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2815 pData->sigRssiResult[i].numRssi) ||
2816 nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2818 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2819 pData->sigRssiResult[i].rssi))
2820 goto fail;
2821 nla_nest_end(skb, ap);
2822 }
2823 nla_nest_end(skb, aps);
2824 if (nla_put_u8(skb,
2825 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2826 pData->moreData))
2827 goto fail;
2828 }
2829 cfg80211_vendor_event(skb, GFP_KERNEL);
2830 return;
2831fail:
2832 kfree_skb(skb);
2833 return;
2834}
2835
2836static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2837 void *pMsg)
2838{
2839 struct sk_buff *skb;
2840 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2841 tpSirWifiFullScanResultEvent pData =
2842 (tpSirWifiFullScanResultEvent) (pMsg);
2843
2844 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2845 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2846 "or pData(%p) is null"), pData);
2847 return;
2848 }
2849
2850 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2851 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2852 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2853 GFP_KERNEL);
2854
2855 if (!skb) {
2856 hddLog(VOS_TRACE_LEVEL_ERROR,
2857 FL("cfg80211_vendor_event_alloc failed"));
2858 return;
2859 }
2860
2861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2862 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2863 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2864 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2865 "Ssid (%s)"
2866 "Bssid (" MAC_ADDRESS_STR ")"
2867 "Channel (%u)"
2868 "Rssi (%d)"
2869 "RTT (%u)"
2870 "RTT_SD (%u)"),
2871 pData->ap.ts,
2872 pData->ap.ssid,
2873 MAC_ADDR_ARRAY(pData->ap.bssid),
2874 pData->ap.channel,
2875 pData->ap.rssi,
2876 pData->ap.rtt,
2877 pData->ap.rtt_sd);
2878 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2879 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2880 pData->requestId) ||
2881 nla_put_u64(skb,
2882 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2883 pData->ap.ts) ||
2884 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2885 sizeof(pData->ap.ssid),
2886 pData->ap.ssid) ||
2887 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2888 WNI_CFG_BSSID_LEN,
2889 pData->ap.bssid) ||
2890 nla_put_u32(skb,
2891 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2892 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05302893 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302894 pData->ap.rssi) ||
2895 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2896 pData->ap.rtt) ||
2897 nla_put_u32(skb,
2898 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2899 pData->ap.rtt_sd) ||
2900 nla_put_u16(skb,
2901 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2902 pData->ap.beaconPeriod) ||
2903 nla_put_u16(skb,
2904 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2905 pData->ap.capability) ||
2906 nla_put_u32(skb,
2907 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2908 pData->ieLength))
2909 {
2910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2911 goto nla_put_failure;
2912 }
2913 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2914 pData->ieLength,
2915 pData->ie))
2916 {
2917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2918 goto nla_put_failure;
2919 }
2920
2921 cfg80211_vendor_event(skb, GFP_KERNEL);
2922 return;
2923
2924nla_put_failure:
2925 kfree_skb(skb);
2926 return;
2927}
2928
2929static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2930 void *pMsg)
2931{
2932 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2933 struct sk_buff *skb = NULL;
2934 tpSirEXTScanResultsAvailableIndParams pData =
2935 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2936
2937 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2939 "or pData(%p) is null"), pData);
2940 return;
2941 }
2942
2943 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2944 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2945 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2946 GFP_KERNEL);
2947
2948 if (!skb) {
2949 hddLog(VOS_TRACE_LEVEL_ERROR,
2950 FL("cfg80211_vendor_event_alloc failed"));
2951 return;
2952 }
2953
2954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2955 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2956 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2957 pData->numResultsAvailable);
2958 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2959 pData->requestId) ||
2960 nla_put_u32(skb,
2961 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2962 pData->numResultsAvailable)) {
2963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2964 goto nla_put_failure;
2965 }
2966
2967 cfg80211_vendor_event(skb, GFP_KERNEL);
2968 return;
2969
2970nla_put_failure:
2971 kfree_skb(skb);
2972 return;
2973}
2974
2975static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2976{
2977 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2978 struct sk_buff *skb = NULL;
2979 tpSirEXTScanProgressIndParams pData =
2980 (tpSirEXTScanProgressIndParams) pMsg;
2981
2982 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2984 "or pData(%p) is null"), pData);
2985 return;
2986 }
2987
2988 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2989 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2990 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2991 GFP_KERNEL);
2992
2993 if (!skb) {
2994 hddLog(VOS_TRACE_LEVEL_ERROR,
2995 FL("cfg80211_vendor_event_alloc failed"));
2996 return;
2997 }
2998 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2999 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3000 pData->extScanEventType);
3001 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3002 pData->status);
3003
3004 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3005 pData->extScanEventType) ||
3006 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303007 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3008 pData->requestId) ||
3009 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303010 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3011 pData->status)) {
3012 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3013 goto nla_put_failure;
3014 }
3015
3016 cfg80211_vendor_event(skb, GFP_KERNEL);
3017 return;
3018
3019nla_put_failure:
3020 kfree_skb(skb);
3021 return;
3022}
3023
3024void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3025 void *pMsg)
3026{
3027 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3028
3029 if (wlan_hdd_validate_context(pHddCtx)) {
Dasari Srinivasb46ed1d2014-10-08 13:03:08 +05303030 hddLog(VOS_TRACE_LEVEL_INFO, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303031 return;
3032 }
3033
3034 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3035
3036
3037 switch(evType) {
3038 case SIR_HAL_EXTSCAN_START_RSP:
3039 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3040 break;
3041
3042 case SIR_HAL_EXTSCAN_STOP_RSP:
3043 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3044 break;
3045 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3046 /* There is no need to send this response to upper layer
3047 Just log the message */
3048 hddLog(VOS_TRACE_LEVEL_INFO,
3049 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3050 break;
3051 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3052 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3053 break;
3054
3055 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3056 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3057 break;
3058
3059 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3060 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3061 break;
3062
3063 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3064 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3065 break;
3066 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3067 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3068 break;
3069 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3070 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3071 break;
3072 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3073 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3074 break;
3075 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3076 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3077 break;
3078 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3079 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3080 break;
3081 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3082 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3083 break;
3084 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3085 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3086 break;
3087 default:
3088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3089 break;
3090 }
3091}
3092
3093static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3094 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303095 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096{
Dino Myclee8843b32014-07-04 14:21:45 +05303097 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303098 struct net_device *dev = wdev->netdev;
3099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3100 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3101 struct nlattr
3102 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3103 eHalStatus status;
3104
3105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3106 status = wlan_hdd_validate_context(pHddCtx);
3107 if (0 != status)
3108 {
3109 hddLog(VOS_TRACE_LEVEL_ERROR,
3110 FL("HDD context is not valid"));
3111 return -EINVAL;
3112 }
Dino Myclee8843b32014-07-04 14:21:45 +05303113 /* check the EXTScan Capability */
3114 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3115 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3116 {
3117 hddLog(VOS_TRACE_LEVEL_ERROR,
3118 FL("EXTScan not enabled/supported by Firmware"));
3119 return -EINVAL;
3120 }
3121
Dino Mycle6fb96c12014-06-10 11:52:40 +05303122 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3123 data, dataLen,
3124 wlan_hdd_extscan_config_policy)) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3126 return -EINVAL;
3127 }
3128
3129 /* Parse and fetch request Id */
3130 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3132 return -EINVAL;
3133 }
3134
Dino Mycle6fb96c12014-06-10 11:52:40 +05303135
Dino Myclee8843b32014-07-04 14:21:45 +05303136 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303139
Dino Myclee8843b32014-07-04 14:21:45 +05303140 reqMsg.sessionId = pAdapter->sessionId;
3141 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303142
Dino Myclee8843b32014-07-04 14:21:45 +05303143 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 if (!HAL_STATUS_SUCCESS(status)) {
3145 hddLog(VOS_TRACE_LEVEL_ERROR,
3146 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303147 return -EINVAL;
3148 }
3149
3150 return 0;
3151}
3152
3153
3154static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3155 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303156 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303157{
Dino Myclee8843b32014-07-04 14:21:45 +05303158 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 struct net_device *dev = wdev->netdev;
3160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3161 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3162 struct nlattr
3163 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3164 eHalStatus status;
3165
3166 status = wlan_hdd_validate_context(pHddCtx);
3167 if (0 != status)
3168 {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("HDD context is not valid"));
3171 return -EINVAL;
3172 }
Dino Myclee8843b32014-07-04 14:21:45 +05303173 /* check the EXTScan Capability */
3174 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3175 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3176 {
3177 hddLog(VOS_TRACE_LEVEL_ERROR,
3178 FL("EXTScan not enabled/supported by Firmware"));
3179 return -EINVAL;
3180 }
3181
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3183 data, dataLen,
3184 wlan_hdd_extscan_config_policy)) {
3185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3186 return -EINVAL;
3187 }
3188 /* Parse and fetch request Id */
3189 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3191 return -EINVAL;
3192 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193
Dino Myclee8843b32014-07-04 14:21:45 +05303194 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3196
Dino Myclee8843b32014-07-04 14:21:45 +05303197 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303198
Dino Myclee8843b32014-07-04 14:21:45 +05303199 reqMsg.sessionId = pAdapter->sessionId;
3200 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303201
3202 /* Parse and fetch flush parameter */
3203 if (!tb
3204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3205 {
3206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3207 goto failed;
3208 }
Dino Myclee8843b32014-07-04 14:21:45 +05303209 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303210 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3211
Dino Myclee8843b32014-07-04 14:21:45 +05303212 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213
Dino Myclee8843b32014-07-04 14:21:45 +05303214 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 if (!HAL_STATUS_SUCCESS(status)) {
3216 hddLog(VOS_TRACE_LEVEL_ERROR,
3217 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303218 return -EINVAL;
3219 }
3220 return 0;
3221
3222failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 return -EINVAL;
3224}
3225
3226static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3227 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303228 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229{
3230 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3231 struct net_device *dev = wdev->netdev;
3232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3233 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3234 struct nlattr
3235 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3236 struct nlattr
3237 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3238 struct nlattr *apTh;
3239 eHalStatus status;
3240 tANI_U8 i = 0;
3241 int rem;
3242
3243 status = wlan_hdd_validate_context(pHddCtx);
3244 if (0 != status)
3245 {
3246 hddLog(VOS_TRACE_LEVEL_ERROR,
3247 FL("HDD context is not valid"));
3248 return -EINVAL;
3249 }
Dino Myclee8843b32014-07-04 14:21:45 +05303250 /* check the EXTScan Capability */
3251 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3252 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3253 {
3254 hddLog(VOS_TRACE_LEVEL_ERROR,
3255 FL("EXTScan not enabled/supported by Firmware"));
3256 return -EINVAL;
3257 }
3258
Dino Mycle6fb96c12014-06-10 11:52:40 +05303259 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3260 data, dataLen,
3261 wlan_hdd_extscan_config_policy)) {
3262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3263 return -EINVAL;
3264 }
3265
3266 /* Parse and fetch request Id */
3267 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3269 return -EINVAL;
3270 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3272 vos_mem_malloc(sizeof(*pReqMsg));
3273 if (!pReqMsg) {
3274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3275 return -ENOMEM;
3276 }
3277
Dino Myclee8843b32014-07-04 14:21:45 +05303278
Dino Mycle6fb96c12014-06-10 11:52:40 +05303279 pReqMsg->requestId = nla_get_u32(
3280 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3281 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3282
3283 /* Parse and fetch number of APs */
3284 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3286 goto fail;
3287 }
3288
3289 pReqMsg->sessionId = pAdapter->sessionId;
3290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3291
3292 pReqMsg->numAp = nla_get_u32(
3293 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3294 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3295
3296 nla_for_each_nested(apTh,
3297 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3298 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3299 nla_data(apTh), nla_len(apTh),
3300 NULL)) {
3301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3302 goto fail;
3303 }
3304
3305 /* Parse and fetch MAC address */
3306 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3308 goto fail;
3309 }
3310 memcpy(pReqMsg->ap[i].bssid, nla_data(
3311 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3312 sizeof(tSirMacAddr));
3313 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3314
3315 /* Parse and fetch low RSSI */
3316 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3318 goto fail;
3319 }
3320 pReqMsg->ap[i].low = nla_get_s32(
3321 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3322 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3323
3324 /* Parse and fetch high RSSI */
3325 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3327 goto fail;
3328 }
3329 pReqMsg->ap[i].high = nla_get_s32(
3330 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3332 pReqMsg->ap[i].high);
3333
3334 /* Parse and fetch channel */
3335 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3337 goto fail;
3338 }
3339 pReqMsg->ap[i].channel = nla_get_u32(
3340 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3341 hddLog(VOS_TRACE_LEVEL_INFO,
3342 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3343 i++;
3344 }
3345 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3346 if (!HAL_STATUS_SUCCESS(status)) {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,
3348 FL("sme_SetBssHotlist failed(err=%d)"), status);
3349 vos_mem_free(pReqMsg);
3350 return -EINVAL;
3351 }
3352
Dino Myclee8843b32014-07-04 14:21:45 +05303353 vos_mem_free(pReqMsg);
3354
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 return 0;
3356
3357fail:
3358 vos_mem_free(pReqMsg);
3359 return -EINVAL;
3360}
3361
3362static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3363 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303364 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365{
3366 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3367 struct net_device *dev = wdev->netdev;
3368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3369 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3370 struct nlattr
3371 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3372 struct nlattr
3373 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3374 struct nlattr *apTh;
3375 eHalStatus status;
3376 int i = 0;
3377 int rem;
3378
3379 status = wlan_hdd_validate_context(pHddCtx);
3380 if (0 != status)
3381 {
3382 hddLog(VOS_TRACE_LEVEL_ERROR,
3383 FL("HDD context is not valid"));
3384 return -EINVAL;
3385 }
Dino Myclee8843b32014-07-04 14:21:45 +05303386 /* check the EXTScan Capability */
3387 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3388 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3389 {
3390 hddLog(VOS_TRACE_LEVEL_ERROR,
3391 FL("EXTScan not enabled/supported by Firmware"));
3392 return -EINVAL;
3393 }
3394
Dino Mycle6fb96c12014-06-10 11:52:40 +05303395 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3396 data, dataLen,
3397 wlan_hdd_extscan_config_policy)) {
3398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3399 return -EINVAL;
3400 }
3401
3402 /* Parse and fetch request Id */
3403 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3405 return -EINVAL;
3406 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303408 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303409 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3411 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 }
3413
Dino Myclee8843b32014-07-04 14:21:45 +05303414
3415
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416 pReqMsg->requestId = nla_get_u32(
3417 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3419
3420 /* Parse and fetch RSSI sample size */
3421 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3422 {
3423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3424 goto fail;
3425 }
3426 pReqMsg->rssiSampleSize = nla_get_u32(
3427 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3428 hddLog(VOS_TRACE_LEVEL_INFO,
3429 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3430
3431 /* Parse and fetch lost AP sample size */
3432 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3433 {
3434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3435 goto fail;
3436 }
3437 pReqMsg->lostApSampleSize = nla_get_u32(
3438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3439 hddLog(VOS_TRACE_LEVEL_INFO,
3440 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3441 /* Parse and fetch minimum Breaching */
3442 if (!tb
3443 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3445 goto fail;
3446 }
3447 pReqMsg->minBreaching = nla_get_u32(
3448 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3449 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3450
3451 /* Parse and fetch number of APs */
3452 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3454 goto fail;
3455 }
3456 pReqMsg->numAp = nla_get_u32(
3457 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3459
3460 pReqMsg->sessionId = pAdapter->sessionId;
3461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3462
3463 nla_for_each_nested(apTh,
3464 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3465 if(nla_parse(tb2,
3466 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3467 nla_data(apTh), nla_len(apTh),
3468 NULL)) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3470 goto fail;
3471 }
3472
3473 /* Parse and fetch MAC address */
3474 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3476 goto fail;
3477 }
3478 memcpy(pReqMsg->ap[i].bssid, nla_data(
3479 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3480 sizeof(tSirMacAddr));
3481
3482 /* Parse and fetch low RSSI */
3483 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3485 goto fail;
3486 }
3487 pReqMsg->ap[i].low = nla_get_s32(
3488 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3490
3491 /* Parse and fetch high RSSI */
3492 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3494 goto fail;
3495 }
3496 pReqMsg->ap[i].high = nla_get_s32(
3497 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3498 hddLog(VOS_TRACE_LEVEL_INFO,
3499 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3500
3501 /* Parse and fetch channel */
3502 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3504 goto fail;
3505 }
3506 pReqMsg->ap[i].channel = nla_get_u32(
3507 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3508 hddLog(VOS_TRACE_LEVEL_INFO,
3509 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3510 i++;
3511 }
3512
3513 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3514 if (!HAL_STATUS_SUCCESS(status)) {
3515 hddLog(VOS_TRACE_LEVEL_ERROR,
3516 FL("sme_SetSignificantChange failed(err=%d)"), status);
3517 vos_mem_free(pReqMsg);
3518 return -EINVAL;
3519 }
Dino Myclee8843b32014-07-04 14:21:45 +05303520 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3522 return 0;
3523
3524fail:
3525 vos_mem_free(pReqMsg);
3526 return -EINVAL;
3527}
3528
3529static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3530 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303531 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532{
3533 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3534 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3535 tANI_U8 numChannels = 0;
3536 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3537 tANI_U32 requestId;
3538 tWifiBand wifiBand;
3539 eHalStatus status;
3540 struct sk_buff *replySkb;
3541 tANI_U8 i;
3542
3543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3544 status = wlan_hdd_validate_context(pHddCtx);
3545 if (0 != status)
3546 {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("HDD context is not valid"));
3549 return -EINVAL;
3550 }
Dino Myclee8843b32014-07-04 14:21:45 +05303551 /* check the EXTScan Capability */
3552 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3553 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3554 {
3555 hddLog(VOS_TRACE_LEVEL_ERROR,
3556 FL("EXTScan not enabled/supported by Firmware"));
3557 return -EINVAL;
3558 }
3559
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3561 data, dataLen,
3562 wlan_hdd_extscan_config_policy)) {
3563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3564 return -EINVAL;
3565 }
3566
3567 /* Parse and fetch request Id */
3568 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3570 return -EINVAL;
3571 }
3572 requestId = nla_get_u32(
3573 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3574 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3575
3576 /* Parse and fetch wifi band */
3577 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3578 {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3580 return -EINVAL;
3581 }
3582 wifiBand = nla_get_u32(
3583 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3585
3586 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3587 wifiBand, ChannelList,
3588 &numChannels);
3589 if (eHAL_STATUS_SUCCESS != status) {
3590 hddLog(VOS_TRACE_LEVEL_ERROR,
3591 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3592 return -EINVAL;
3593 }
3594 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3595 for (i = 0; i < numChannels; i++)
3596 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3597
3598 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3599 sizeof(u32) * numChannels +
3600 NLMSG_HDRLEN);
3601
3602 if (!replySkb) {
3603 hddLog(VOS_TRACE_LEVEL_ERROR,
3604 FL("valid channels: buffer alloc fail"));
3605 return -EINVAL;
3606 }
3607 if (nla_put_u32(replySkb,
3608 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3609 numChannels) ||
3610 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3611 sizeof(u32) * numChannels, ChannelList)) {
3612
3613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3614 kfree_skb(replySkb);
3615 return -EINVAL;
3616 }
3617
3618 return cfg80211_vendor_cmd_reply(replySkb);
3619}
3620
3621static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3622 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303623 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624{
Dino Myclee8843b32014-07-04 14:21:45 +05303625 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303626 struct net_device *dev = wdev->netdev;
3627 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3628 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3629 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3630 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3631 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3632 struct nlattr *buckets;
3633 struct nlattr *channels;
3634 int rem1;
3635 int rem2;
3636 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303637 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303638
3639 status = wlan_hdd_validate_context(pHddCtx);
3640 if (0 != status)
3641 {
3642 hddLog(VOS_TRACE_LEVEL_ERROR,
3643 FL("HDD context is not valid"));
3644 return -EINVAL;
3645 }
Dino Myclee8843b32014-07-04 14:21:45 +05303646 /* check the EXTScan Capability */
3647 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3648 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3649 {
3650 hddLog(VOS_TRACE_LEVEL_ERROR,
3651 FL("EXTScan not enabled/supported by Firmware"));
3652 return -EINVAL;
3653 }
3654
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3656 data, dataLen,
3657 wlan_hdd_extscan_config_policy)) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3659 return -EINVAL;
3660 }
3661
3662 /* Parse and fetch request Id */
3663 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3665 return -EINVAL;
3666 }
3667
Dino Myclee8843b32014-07-04 14:21:45 +05303668 pReqMsg = (tpSirEXTScanStartReqParams)
3669 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3672 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 }
3674
3675 pReqMsg->requestId = nla_get_u32(
3676 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3678
3679 pReqMsg->sessionId = pAdapter->sessionId;
3680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3681
3682 /* Parse and fetch base period */
3683 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3685 goto fail;
3686 }
3687 pReqMsg->basePeriod = nla_get_u32(
3688 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3690 pReqMsg->basePeriod);
3691
3692 /* Parse and fetch max AP per scan */
3693 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3695 goto fail;
3696 }
3697 pReqMsg->maxAPperScan = nla_get_u32(
3698 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3699 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3700 pReqMsg->maxAPperScan);
3701
3702 /* Parse and fetch report threshold */
3703 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3705 goto fail;
3706 }
3707 pReqMsg->reportThreshold = nla_get_u8(
3708 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3710 pReqMsg->reportThreshold);
3711
3712 /* Parse and fetch number of buckets */
3713 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3715 goto fail;
3716 }
3717 pReqMsg->numBuckets = nla_get_u8(
3718 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3719 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3720 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3721 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3722 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3723 }
3724 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3725 pReqMsg->numBuckets);
3726 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3728 goto fail;
3729 }
3730
3731 nla_for_each_nested(buckets,
3732 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3733 if(nla_parse(bucket,
3734 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3735 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3737 goto fail;
3738 }
3739
3740 /* Parse and fetch bucket spec */
3741 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3743 goto fail;
3744 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303745
3746 pReqMsg->buckets[index].bucket = nla_get_u8(
3747 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3748
3749 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
3750 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303751
3752 /* Parse and fetch wifi band */
3753 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3755 goto fail;
3756 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303757 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303758 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303760 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761
3762 /* Parse and fetch period */
3763 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3765 goto fail;
3766 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303767 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3769 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303770 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771
3772 /* Parse and fetch report events */
3773 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3775 goto fail;
3776 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303777 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3779 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303780 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781
3782 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303783 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
3784 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3786 goto fail;
3787 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303788 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3790 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303791 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303792
3793 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3795 goto fail;
3796 }
3797
3798 j = 0;
3799 nla_for_each_nested(channels,
3800 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3801 if(nla_parse(channel,
3802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3803 nla_data(channels), nla_len(channels),
3804 NULL)) { //wlan_hdd_extscan_config_policy here
3805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3806 goto fail;
3807 }
3808
3809 /* Parse and fetch channel */
3810 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3812 goto fail;
3813 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303814 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3816 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303817 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303818
3819 /* Parse and fetch dwell time */
3820 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3822 goto fail;
3823 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303824 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303825 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3826 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303827 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
3829 /* Parse and fetch channel spec passive */
3830 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3831 hddLog(VOS_TRACE_LEVEL_ERROR,
3832 FL("attr channel spec passive failed"));
3833 goto fail;
3834 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303835 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3837 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303838 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839 j++;
3840 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05303841 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 }
3843 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3844 if (!HAL_STATUS_SUCCESS(status)) {
3845 hddLog(VOS_TRACE_LEVEL_ERROR,
3846 FL("sme_EXTScanStart failed(err=%d)"), status);
3847 vos_mem_free(pReqMsg);
3848 return -EINVAL;
3849 }
3850
Dino Myclee8843b32014-07-04 14:21:45 +05303851 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303852 return 0;
3853
3854fail:
3855 vos_mem_free(pReqMsg);
3856 return -EINVAL;
3857}
3858
3859static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3860 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303861 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862{
Dino Myclee8843b32014-07-04 14:21:45 +05303863 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 struct net_device *dev = wdev->netdev;
3865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3867 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3868 eHalStatus status;
3869
3870 status = wlan_hdd_validate_context(pHddCtx);
3871 if (0 != status)
3872 {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("HDD context is not valid"));
3875 return -EINVAL;
3876 }
Dino Myclee8843b32014-07-04 14:21:45 +05303877 /* check the EXTScan Capability */
3878 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3879 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3880 {
3881 hddLog(VOS_TRACE_LEVEL_ERROR,
3882 FL("EXTScan not enabled/supported by Firmware"));
3883 return -EINVAL;
3884 }
3885
Dino Mycle6fb96c12014-06-10 11:52:40 +05303886 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3887 data, dataLen,
3888 wlan_hdd_extscan_config_policy)) {
3889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3890 return -EINVAL;
3891 }
3892
3893 /* Parse and fetch request Id */
3894 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3896 return -EINVAL;
3897 }
3898
Dino Myclee8843b32014-07-04 14:21:45 +05303899 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902
Dino Myclee8843b32014-07-04 14:21:45 +05303903 reqMsg.sessionId = pAdapter->sessionId;
3904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303905
Dino Myclee8843b32014-07-04 14:21:45 +05303906 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303907 if (!HAL_STATUS_SUCCESS(status)) {
3908 hddLog(VOS_TRACE_LEVEL_ERROR,
3909 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 return -EINVAL;
3911 }
3912
3913 return 0;
3914}
3915
3916static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3917 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303918 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919{
Dino Myclee8843b32014-07-04 14:21:45 +05303920 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 struct net_device *dev = wdev->netdev;
3922 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3923 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3924 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3925 eHalStatus status;
3926
3927 status = wlan_hdd_validate_context(pHddCtx);
3928 if (0 != status)
3929 {
3930 hddLog(VOS_TRACE_LEVEL_ERROR,
3931 FL("HDD context is not valid"));
3932 return -EINVAL;
3933 }
Dino Myclee8843b32014-07-04 14:21:45 +05303934 /* check the EXTScan Capability */
3935 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3936 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR,
3939 FL("EXTScan not enabled/supported by Firmware"));
3940 return -EINVAL;
3941 }
3942
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3944 data, dataLen,
3945 wlan_hdd_extscan_config_policy)) {
3946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3947 return -EINVAL;
3948 }
3949
3950 /* Parse and fetch request Id */
3951 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3953 return -EINVAL;
3954 }
3955
Dino Myclee8843b32014-07-04 14:21:45 +05303956 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959
Dino Myclee8843b32014-07-04 14:21:45 +05303960 reqMsg.sessionId = pAdapter->sessionId;
3961 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962
Dino Myclee8843b32014-07-04 14:21:45 +05303963 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303964 if (!HAL_STATUS_SUCCESS(status)) {
3965 hddLog(VOS_TRACE_LEVEL_ERROR,
3966 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 return -EINVAL;
3968 }
3969
3970 return 0;
3971}
3972
3973static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3974 struct wiphy *wiphy,
3975 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303976 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303977{
Dino Myclee8843b32014-07-04 14:21:45 +05303978 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 struct net_device *dev = wdev->netdev;
3980 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3981 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3982 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3983 eHalStatus status;
3984
3985 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3986 status = wlan_hdd_validate_context(pHddCtx);
3987 if (0 != status)
3988 {
3989 hddLog(VOS_TRACE_LEVEL_ERROR,
3990 FL("HDD context is not valid"));
3991 return -EINVAL;
3992 }
Dino Myclee8843b32014-07-04 14:21:45 +05303993 /* check the EXTScan Capability */
3994 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3995 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3996 {
3997 hddLog(VOS_TRACE_LEVEL_ERROR,
3998 FL("EXTScan not enabled/supported by Firmware"));
3999 return -EINVAL;
4000 }
4001
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4003 data, dataLen,
4004 wlan_hdd_extscan_config_policy)) {
4005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4006 return -EINVAL;
4007 }
4008
4009 /* Parse and fetch request Id */
4010 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4012 return -EINVAL;
4013 }
4014
Dino Mycle6fb96c12014-06-10 11:52:40 +05304015
Dino Myclee8843b32014-07-04 14:21:45 +05304016 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304017 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304018 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019
Dino Myclee8843b32014-07-04 14:21:45 +05304020 reqMsg.sessionId = pAdapter->sessionId;
4021 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022
Dino Myclee8843b32014-07-04 14:21:45 +05304023 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304024 if (!HAL_STATUS_SUCCESS(status)) {
4025 hddLog(VOS_TRACE_LEVEL_ERROR,
4026 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304027 return -EINVAL;
4028 }
4029
4030 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
4031 return 0;
4032}
4033
4034#endif /* WLAN_FEATURE_EXTSCAN */
4035
Atul Mittal115287b2014-07-08 13:26:33 +05304036/*EXT TDLS*/
4037static const struct nla_policy
4038wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4039{
4040 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4041 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4042 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4043 {.type = NLA_S32 },
4044 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4045 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4046
4047};
4048
4049static const struct nla_policy
4050wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4051{
4052 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4053
4054};
4055
4056static const struct nla_policy
4057wlan_hdd_tdls_config_state_change_policy[
4058 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4059{
4060 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4061 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4062 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304063 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4064 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4065 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304066
4067};
4068
4069static const struct nla_policy
4070wlan_hdd_tdls_config_get_status_policy[
4071 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4072{
4073 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4074 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4075 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304076 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4077 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4078 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304079
4080};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304081
4082static const struct nla_policy
4083wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4084{
4085 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4086};
4087
4088static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4089 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304090 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304091 int data_len)
4092{
4093
4094 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4095 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4096
4097 if (0 != wlan_hdd_validate_context(pHddCtx)){
4098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
4099 return -EINVAL;
4100 }
4101 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4103 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304104 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304105 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4107 return -ENOTSUPP;
4108 }
4109
4110 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4111 data, data_len, wlan_hdd_mac_config)) {
4112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4113 return -EINVAL;
4114 }
4115
4116 /* Parse and fetch mac address */
4117 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4119 return -EINVAL;
4120 }
4121
4122 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4123 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4124 VOS_MAC_ADDR_LAST_3_BYTES);
4125
Siddharth Bhal76972212014-10-15 16:22:51 +05304126 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4127
4128 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304129 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4130 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304131 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4132 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4133 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4134 {
4135 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4136 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4137 VOS_MAC_ADDRESS_LEN);
4138 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304139 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304140
Siddharth Bhal76972212014-10-15 16:22:51 +05304141 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4142 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304143 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4144 }
4145
4146 return 0;
4147}
4148
Atul Mittal115287b2014-07-08 13:26:33 +05304149static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4150 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304151 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304152 int data_len)
4153{
4154 u8 peer[6] = {0};
4155 struct net_device *dev = wdev->netdev;
4156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4157 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4158 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4159 eHalStatus ret;
4160 tANI_S32 state;
4161 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304162 tANI_S32 global_operating_class = 0;
4163 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304164 struct sk_buff *skb = NULL;
4165
4166 ret = wlan_hdd_validate_context(pHddCtx);
4167 if (0 != ret) {
4168
4169 return -EINVAL;
4170 }
4171 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4172
4173 return -ENOTSUPP;
4174 }
4175 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4176 data, data_len,
4177 wlan_hdd_tdls_config_get_status_policy)) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4179 return -EINVAL;
4180 }
4181
4182 /* Parse and fetch mac address */
4183 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4185 return -EINVAL;
4186 }
4187
4188 memcpy(peer, nla_data(
4189 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4190 sizeof(peer));
4191 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4192
4193 ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
4194
4195 if (0 != ret) {
4196 hddLog(VOS_TRACE_LEVEL_ERROR,
4197 FL("get status Failed"));
4198 return -EINVAL;
4199 }
4200 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304201 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304202 NLMSG_HDRLEN);
4203
4204 if (!skb) {
4205 hddLog(VOS_TRACE_LEVEL_ERROR,
4206 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4207 return -EINVAL;
4208 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304209 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 +05304210 reason,
4211 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304212 global_operating_class,
4213 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304214 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304215 if (nla_put_s32(skb,
4216 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4217 state) ||
4218 nla_put_s32(skb,
4219 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4220 reason) ||
4221 nla_put_s32(skb,
4222 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4223 global_operating_class) ||
4224 nla_put_s32(skb,
4225 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4226 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304227
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4229 goto nla_put_failure;
4230 }
4231
4232 return cfg80211_vendor_cmd_reply(skb);
4233
4234nla_put_failure:
4235 kfree_skb(skb);
4236 return -EINVAL;
4237}
4238
4239static int wlan_hdd_cfg80211_exttdls_callback(tANI_U8* mac,
4240 tANI_S32 state,
4241 tANI_S32 reason,
4242 void *ctx)
4243{
4244 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
4245 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4246 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304247 tANI_S32 global_operating_class = 0;
4248 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304249
4250 if (wlan_hdd_validate_context(pHddCtx)) {
4251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "));
4252 return -EINVAL;
4253 }
4254
4255 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4256
4257 return -ENOTSUPP;
4258 }
4259 skb = cfg80211_vendor_event_alloc(
4260 pHddCtx->wiphy,
4261 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4262 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4263 GFP_KERNEL);
4264
4265 if (!skb) {
4266 hddLog(VOS_TRACE_LEVEL_ERROR,
4267 FL("cfg80211_vendor_event_alloc failed"));
4268 return -EINVAL;
4269 }
4270 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304271 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4272 reason,
4273 state,
4274 global_operating_class,
4275 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304276 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4277 MAC_ADDR_ARRAY(mac));
4278
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304279 if (nla_put(skb,
4280 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4281 VOS_MAC_ADDR_SIZE, mac) ||
4282 nla_put_s32(skb,
4283 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4284 state) ||
4285 nla_put_s32(skb,
4286 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4287 reason) ||
4288 nla_put_s32(skb,
4289 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4290 channel) ||
4291 nla_put_s32(skb,
4292 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4293 global_operating_class)
4294 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4296 goto nla_put_failure;
4297 }
4298
4299 cfg80211_vendor_event(skb, GFP_KERNEL);
4300 return (0);
4301
4302nla_put_failure:
4303 kfree_skb(skb);
4304 return -EINVAL;
4305}
4306
4307static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4308 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304309 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304310 int data_len)
4311{
4312 u8 peer[6] = {0};
4313 struct net_device *dev = wdev->netdev;
4314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4316 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4317 eHalStatus status;
4318 tdls_req_params_t pReqMsg = {0};
4319
4320 status = wlan_hdd_validate_context(pHddCtx);
4321 if (0 != status) {
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 FL("HDD context is not valid"));
4324 return -EINVAL;
4325 }
4326 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4327
4328 return -ENOTSUPP;
4329 }
4330 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4331 data, data_len,
4332 wlan_hdd_tdls_config_enable_policy)) {
4333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4334 return -EINVAL;
4335 }
4336
4337 /* Parse and fetch mac address */
4338 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4340 return -EINVAL;
4341 }
4342
4343 memcpy(peer, nla_data(
4344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4345 sizeof(peer));
4346 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4347
4348 /* Parse and fetch channel */
4349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4351 return -EINVAL;
4352 }
4353 pReqMsg.channel = nla_get_s32(
4354 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4356
4357 /* Parse and fetch global operating class */
4358 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4360 return -EINVAL;
4361 }
4362 pReqMsg.global_operating_class = nla_get_s32(
4363 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4364 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4365 pReqMsg.global_operating_class);
4366
4367 /* Parse and fetch latency ms */
4368 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4369 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4370 return -EINVAL;
4371 }
4372 pReqMsg.max_latency_ms = nla_get_s32(
4373 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4375 pReqMsg.max_latency_ms);
4376
4377 /* Parse and fetch required bandwidth kbps */
4378 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4380 return -EINVAL;
4381 }
4382
4383 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4384 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4386 pReqMsg.min_bandwidth_kbps);
4387
4388 return (wlan_hdd_tdls_extctrl_config_peer(pAdapter,
4389 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304390 &pReqMsg,
Atul Mittal115287b2014-07-08 13:26:33 +05304391 wlan_hdd_cfg80211_exttdls_callback));
4392}
4393
4394static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4395 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304396 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304397 int data_len)
4398{
4399 u8 peer[6] = {0};
4400 struct net_device *dev = wdev->netdev;
4401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4402 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4403 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4404 eHalStatus status;
4405
4406 status = wlan_hdd_validate_context(pHddCtx);
4407 if (0 != status) {
4408 hddLog(VOS_TRACE_LEVEL_ERROR,
4409 FL("HDD context is not valid"));
4410 return -EINVAL;
4411 }
4412 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
4413
4414 return -ENOTSUPP;
4415 }
4416 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4417 data, data_len,
4418 wlan_hdd_tdls_config_disable_policy)) {
4419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4420 return -EINVAL;
4421 }
4422 /* Parse and fetch mac address */
4423 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4424 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4425 return -EINVAL;
4426 }
4427
4428 memcpy(peer, nla_data(
4429 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4430 sizeof(peer));
4431 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4432
4433 return (wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer));
4434}
4435
Dasari Srinivas7875a302014-09-26 17:50:57 +05304436static int
4437wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
4438 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304439 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304440{
4441 struct net_device *dev = wdev->netdev;
4442 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4444 struct sk_buff *skb = NULL;
4445 tANI_U32 fset = 0;
4446
4447 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
4448 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
4449 fset |= WIFI_FEATURE_INFRA;
4450 }
4451
4452 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
4453 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
4454 fset |= WIFI_FEATURE_INFRA_5G;
4455 }
4456
4457#ifdef WLAN_FEATURE_P2P
4458 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
4459 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
4460 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
4461 fset |= WIFI_FEATURE_P2P;
4462 }
4463#endif
4464
4465 /* Soft-AP is supported currently by default */
4466 fset |= WIFI_FEATURE_SOFT_AP;
4467
4468#ifdef WLAN_FEATURE_EXTSCAN
4469 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
4470 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
4471 hddLog(LOG1, FL("EXTScan is supported by firmware"));
4472 fset |= WIFI_FEATURE_EXTSCAN;
4473 }
4474#endif
4475
4476#ifdef WLAN_FEATURE_NAN
4477 if (sme_IsFeatureSupportedByFW(NAN)) {
4478 hddLog(LOG1, FL("NAN is supported by firmware"));
4479 fset |= WIFI_FEATURE_NAN;
4480 }
4481#endif
4482
4483 /* D2D RTT is not supported currently by default */
4484 if (sme_IsFeatureSupportedByFW(RTT)) {
4485 hddLog(LOG1, FL("RTT is supported by firmware"));
4486 fset |= WIFI_FEATURE_D2AP_RTT;
4487 }
4488
4489#ifdef FEATURE_WLAN_BATCH_SCAN
4490 if (fset & WIFI_FEATURE_EXTSCAN) {
4491 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
4492 fset &= ~WIFI_FEATURE_BATCH_SCAN;
4493 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
4494 hddLog(LOG1, FL("Batch scan is supported by firmware"));
4495 fset |= WIFI_FEATURE_BATCH_SCAN;
4496 }
4497#endif
4498
4499#ifdef FEATURE_WLAN_SCAN_PNO
4500 if (pHddCtx->cfg_ini->configPNOScanSupport &&
4501 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
4502 hddLog(LOG1, FL("PNO is supported by firmware"));
4503 fset |= WIFI_FEATURE_PNO;
4504 }
4505#endif
4506
4507 /* STA+STA is supported currently by default */
4508 fset |= WIFI_FEATURE_ADDITIONAL_STA;
4509
4510#ifdef FEATURE_WLAN_TDLS
4511 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
4512 sme_IsFeatureSupportedByFW(TDLS)) {
4513 hddLog(LOG1, FL("TDLS is supported by firmware"));
4514 fset |= WIFI_FEATURE_TDLS;
4515 }
4516
4517 /* TDLS_OFFCHANNEL is not supported currently by default */
4518#endif
4519
4520#ifdef WLAN_AP_STA_CONCURRENCY
4521 /* AP+STA concurrency is supported currently by default */
4522 fset |= WIFI_FEATURE_AP_STA;
4523#endif
4524
4525 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
4526 NLMSG_HDRLEN);
4527
4528 if (!skb) {
4529 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4530 return -EINVAL;
4531 }
4532 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
4533
4534 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
4535 hddLog(LOGE, FL("nla put fail"));
4536 goto nla_put_failure;
4537 }
4538
4539 return cfg80211_vendor_cmd_reply(skb);
4540
4541nla_put_failure:
4542 kfree_skb(skb);
4543 return -EINVAL;
4544}
4545
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304546static int
4547wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
4548 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304549 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304550{
4551 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
4552 uint8_t i, feature_sets, max_feature_sets;
4553 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
4554 struct sk_buff *reply_skb;
4555
4556 ENTER();
4557
4558 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
4559 data, data_len, NULL)) {
4560 hddLog(LOGE, FL("Invalid ATTR"));
4561 return -EINVAL;
4562 }
4563
4564 /* Parse and fetch max feature set */
4565 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
4566 hddLog(LOGE, FL("Attr max feature set size failed"));
4567 return -EINVAL;
4568 }
4569 max_feature_sets = nla_get_u32(
4570 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
4571 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
4572
4573 /* Fill feature combination matrix */
4574 feature_sets = 0;
4575 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4576 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4577 WIFI_FEATURE_P2P;
4578
4579 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4580 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4581 WIFI_FEATURE_SOFT_AP;
4582
4583 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4584 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
4585 WIFI_FEATURE_SOFT_AP;
4586
4587 if (feature_sets >= WLAN_HDD_MAX_FEATURE_SET) goto max_buffer_err;
4588 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
4589 WIFI_FEATURE_SOFT_AP |
4590 WIFI_FEATURE_P2P;
4591
4592 /* Add more feature combinations here */
4593
4594 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
4595 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
4596 hddLog(LOG1, "Feature set matrix");
4597 for (i = 0; i < feature_sets; i++)
4598 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
4599
4600 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4601 sizeof(u32) * feature_sets +
4602 NLMSG_HDRLEN);
4603
4604 if (reply_skb) {
4605 if (nla_put_u32(reply_skb,
4606 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
4607 feature_sets) ||
4608 nla_put(reply_skb,
4609 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
4610 sizeof(u32) * feature_sets, feature_set_matrix)) {
4611 hddLog(LOGE, FL("nla put fail"));
4612 kfree_skb(reply_skb);
4613 return -EINVAL;
4614 }
4615
4616 return cfg80211_vendor_cmd_reply(reply_skb);
4617 }
4618 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
4619 return -ENOMEM;
4620
4621max_buffer_err:
4622 hddLog(LOGE, FL("Feature set max buffer size reached. feature_sets(%d) max(%d)"),
4623 feature_sets, WLAN_HDD_MAX_FEATURE_SET);
4624 return -EINVAL;
4625}
4626
Agarwal Ashish738843c2014-09-25 12:27:56 +05304627static const struct nla_policy
4628wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4629 +1] =
4630{
4631 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4632};
4633
4634static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
4635 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304636 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05304637 int data_len)
4638{
4639 struct net_device *dev = wdev->netdev;
4640 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4641 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4642 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4643 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4644 eHalStatus status;
4645 u32 dfsFlag = 0;
4646
4647 status = wlan_hdd_validate_context(pHddCtx);
4648 if (0 != status) {
4649 hddLog(VOS_TRACE_LEVEL_ERROR,
4650 FL("HDD context is not valid"));
4651 return -EINVAL;
4652 }
4653 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4654 data, data_len,
4655 wlan_hdd_set_no_dfs_flag_config_policy)) {
4656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4657 return -EINVAL;
4658 }
4659
4660 /* Parse and fetch required bandwidth kbps */
4661 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
4663 return -EINVAL;
4664 }
4665
4666 dfsFlag = nla_get_u32(
4667 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4668 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
4669 dfsFlag);
4670
4671 pHddCtx->disable_dfs_flag = dfsFlag;
4672
4673 sme_disable_dfs_channel(hHal, dfsFlag);
4674 sme_FilterScanResults(hHal, pAdapter->sessionId);
4675 return 0;
4676}
Atul Mittal115287b2014-07-08 13:26:33 +05304677
Mukul Sharma2a271632014-10-13 14:59:01 +05304678const struct
4679nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
4680{
4681 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
4682 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
4683};
4684
4685static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05304686 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05304687{
4688
4689 u8 bssid[6] = {0};
4690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4691 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
4692 eHalStatus status = eHAL_STATUS_SUCCESS;
4693 v_U32_t isFwrRoamEnabled = FALSE;
4694 int ret;
4695
4696 if (NULL == pHddCtx) {
4697 hddLog(VOS_TRACE_LEVEL_ERROR,
4698 FL("HDD context is not valid"));
4699 return -EINVAL;
4700 }
4701
4702 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
4703 data, data_len,
4704 qca_wlan_vendor_attr);
4705 if (ret){
4706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4707 return -EINVAL;
4708 }
4709
4710 /* Parse and fetch Enable flag */
4711 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
4712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
4713 return -EINVAL;
4714 }
4715
4716 isFwrRoamEnabled = nla_get_u32(
4717 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
4718
4719 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
4720
4721 /* Parse and fetch bssid */
4722 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
4723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
4724 return -EINVAL;
4725 }
4726
4727 memcpy(bssid, nla_data(
4728 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
4729 sizeof(bssid));
4730 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
4731
4732 //Update roaming
4733 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
4734 return status;
4735}
4736
Sunil Duttc69bccb2014-05-26 21:30:20 +05304737const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
4738{
Mukul Sharma2a271632014-10-13 14:59:01 +05304739 {
4740 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4741 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
4742 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4743 WIPHY_VENDOR_CMD_NEED_NETDEV |
4744 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304745 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05304746 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304747#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4748 {
4749 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4750 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
4751 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4752 WIPHY_VENDOR_CMD_NEED_NETDEV |
4753 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304754 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05304755 },
4756
4757 {
4758 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4759 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
4760 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4761 WIPHY_VENDOR_CMD_NEED_NETDEV |
4762 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304763 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05304764 },
4765
4766 {
4767 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4768 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
4769 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4770 WIPHY_VENDOR_CMD_NEED_NETDEV |
4771 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304772 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304774#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775#ifdef WLAN_FEATURE_EXTSCAN
4776 {
4777 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4778 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
4779 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4780 WIPHY_VENDOR_CMD_NEED_NETDEV |
4781 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304782 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05304783 },
4784 {
4785 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4786 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
4787 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4788 WIPHY_VENDOR_CMD_NEED_NETDEV |
4789 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304790 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791 },
4792 {
4793 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4794 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
4795 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4796 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304797 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798 },
4799 {
4800 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4801 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
4802 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4803 WIPHY_VENDOR_CMD_NEED_NETDEV |
4804 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304805 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05304806 },
4807 {
4808 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4809 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
4810 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4811 WIPHY_VENDOR_CMD_NEED_NETDEV |
4812 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304813 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 },
4815 {
4816 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4817 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
4818 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4819 WIPHY_VENDOR_CMD_NEED_NETDEV |
4820 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304821 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 },
4823 {
4824 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4825 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
4826 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4827 WIPHY_VENDOR_CMD_NEED_NETDEV |
4828 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304829 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05304830 },
4831 {
4832 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4833 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
4834 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4835 WIPHY_VENDOR_CMD_NEED_NETDEV |
4836 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304837 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304838 },
4839 {
4840 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4841 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
4842 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4843 WIPHY_VENDOR_CMD_NEED_NETDEV |
4844 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304845 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846 },
4847#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304848/*EXT TDLS*/
4849 {
4850 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4851 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
4852 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4853 WIPHY_VENDOR_CMD_NEED_NETDEV |
4854 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304855 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05304856 },
4857 {
4858 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4859 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
4860 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4861 WIPHY_VENDOR_CMD_NEED_NETDEV |
4862 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304863 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05304864 },
4865 {
4866 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4867 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
4868 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4869 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304870 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05304871 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05304872 {
4873 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4874 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
4875 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4876 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304877 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05304878 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05304879 {
4880 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4881 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
4882 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4883 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304884 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05304885 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304886 {
4887 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4888 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
4889 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4890 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304891 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304892 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304893 {
4894 .info.vendor_id = QCA_NL80211_VENDOR_ID,
4895 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
4896 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
4897 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05304898 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05304899 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304900};
4901
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004902/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304903static const
4904struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004905{
4906#ifdef FEATURE_WLAN_CH_AVOID
4907 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05304908 .vendor_id = QCA_NL80211_VENDOR_ID,
4909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004910 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05304911#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
4912#ifdef WLAN_FEATURE_LINK_LAYER_STATS
4913 {
4914 /* Index = 1*/
4915 .vendor_id = QCA_NL80211_VENDOR_ID,
4916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
4917 },
4918 {
4919 /* Index = 2*/
4920 .vendor_id = QCA_NL80211_VENDOR_ID,
4921 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
4922 },
4923 {
4924 /* Index = 3*/
4925 .vendor_id = QCA_NL80211_VENDOR_ID,
4926 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
4927 },
4928 {
4929 /* Index = 4*/
4930 .vendor_id = QCA_NL80211_VENDOR_ID,
4931 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
4932 },
4933 {
4934 /* Index = 5*/
4935 .vendor_id = QCA_NL80211_VENDOR_ID,
4936 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
4937 },
4938 {
4939 /* Index = 6*/
4940 .vendor_id = QCA_NL80211_VENDOR_ID,
4941 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
4942 },
4943#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05304944#ifdef WLAN_FEATURE_EXTSCAN
4945 {
4946 .vendor_id = QCA_NL80211_VENDOR_ID,
4947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
4948 },
4949 {
4950 .vendor_id = QCA_NL80211_VENDOR_ID,
4951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
4952 },
4953 {
4954 .vendor_id = QCA_NL80211_VENDOR_ID,
4955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
4956 },
4957 {
4958 .vendor_id = QCA_NL80211_VENDOR_ID,
4959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
4960 },
4961 {
4962 .vendor_id = QCA_NL80211_VENDOR_ID,
4963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4964 },
4965 {
4966 .vendor_id = QCA_NL80211_VENDOR_ID,
4967 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4968 },
4969 {
4970 .vendor_id = QCA_NL80211_VENDOR_ID,
4971 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4972 },
4973 {
4974 .vendor_id = QCA_NL80211_VENDOR_ID,
4975 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4976 },
4977 {
4978 .vendor_id = QCA_NL80211_VENDOR_ID,
4979 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4980 },
4981 {
4982 .vendor_id = QCA_NL80211_VENDOR_ID,
4983 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4984 },
4985 {
4986 .vendor_id = QCA_NL80211_VENDOR_ID,
4987 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4988 },
4989 {
4990 .vendor_id = QCA_NL80211_VENDOR_ID,
4991 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4992 },
4993 {
4994 .vendor_id = QCA_NL80211_VENDOR_ID,
4995 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4996 },
4997#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05304998/*EXT TDLS*/
4999 {
5000 .vendor_id = QCA_NL80211_VENDOR_ID,
5001 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5002 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005003};
5004
Jeff Johnson295189b2012-06-20 16:38:30 -07005005/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305006 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007 * This function is called by hdd_wlan_startup()
5008 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305009 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005010 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305011struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005012{
5013 struct wiphy *wiphy;
5014 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305015 /*
5016 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 */
5018 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5019
5020 if (!wiphy)
5021 {
5022 /* Print error and jump into err label and free the memory */
5023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5024 return NULL;
5025 }
5026
Sunil Duttc69bccb2014-05-26 21:30:20 +05305027
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 return wiphy;
5029}
5030
5031/*
5032 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305033 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 * private ioctl to change the band value
5035 */
5036int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5037{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305038 int i, j;
5039 eNVChannelEnabledType channelEnabledState;
5040
Jeff Johnsone7245742012-09-05 17:12:55 -07005041 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305042
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305043 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005044 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305045
5046 if (NULL == wiphy->bands[i])
5047 {
5048 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5049 __func__, i);
5050 continue;
5051 }
5052
5053 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5054 {
5055 struct ieee80211_supported_band *band = wiphy->bands[i];
5056
5057 channelEnabledState = vos_nv_getChannelEnabledState(
5058 band->channels[j].hw_value);
5059
5060 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5061 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305062 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305063 continue;
5064 }
5065 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5066 {
5067 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5068 continue;
5069 }
5070
5071 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5072 NV_CHANNEL_INVALID == channelEnabledState)
5073 {
5074 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5075 }
5076 else if (NV_CHANNEL_DFS == channelEnabledState)
5077 {
5078 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5079 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5080 }
5081 else
5082 {
5083 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5084 |IEEE80211_CHAN_RADAR);
5085 }
5086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 }
5088 return 0;
5089}
5090/*
5091 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 * This function is called by hdd_wlan_startup()
5093 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 * This function is used to initialize and register wiphy structure.
5095 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305096int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005097 struct wiphy *wiphy,
5098 hdd_config_t *pCfg
5099 )
5100{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305101 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305102 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5103
Jeff Johnsone7245742012-09-05 17:12:55 -07005104 ENTER();
5105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 /* Now bind the underlying wlan device with wiphy */
5107 set_wiphy_dev(wiphy, dev);
5108
5109 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005110
Kiet Lam6c583332013-10-14 05:37:09 +05305111#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005112 /* the flag for the other case would be initialzed in
5113 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005114 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305115#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005116
Amar Singhalfddc28c2013-09-05 13:03:40 -07005117 /* This will disable updating of NL channels from passive to
5118 * active if a beacon is received on passive channel. */
5119 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07005120
Amar Singhalfddc28c2013-09-05 13:03:40 -07005121
Amar Singhala49cbc52013-10-08 18:37:44 -07005122
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005123#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005124 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5125 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5126 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005127 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05305128 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005129#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005130
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005131#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005132 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005133#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005134 || pCfg->isFastRoamIniFeatureEnabled
5135#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005136#ifdef FEATURE_WLAN_ESE
5137 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005138#endif
5139 )
5140 {
5141 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5142 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005143#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005144#ifdef FEATURE_WLAN_TDLS
5145 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5146 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5147#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305148#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305149 if (pCfg->configPNOScanSupport)
5150 {
5151 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5152 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5153 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5154 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5155 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305156#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005157
Amar Singhalfddc28c2013-09-05 13:03:40 -07005158#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005159 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5160 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005161 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005162 driver need to determine what to do with both
5163 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005164
5165 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005166#else
5167 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005168#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005169
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305170 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5171
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05305172 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005173
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305174 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5175
Jeff Johnson295189b2012-06-20 16:38:30 -07005176 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305177 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5180 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 | BIT(NL80211_IFTYPE_AP);
5182
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305183 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005184 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5186 if( pCfg->enableMCC )
5187 {
5188 /* Currently, supports up to two channels */
5189 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005190
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305191 if( !pCfg->allowMCCGODiffBI )
5192 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005193
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305194 }
5195 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5196 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005197#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305198 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005199
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 /* Before registering we need to update the ht capabilitied based
5201 * on ini values*/
5202 if( !pCfg->ShortGI20MhzEnable )
5203 {
5204 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5205 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5206 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5207 }
5208
5209 if( !pCfg->ShortGI40MhzEnable )
5210 {
5211 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5212 }
5213
5214 if( !pCfg->nChannelBondingMode5GHz )
5215 {
5216 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5217 }
5218
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305219 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305220 if (true == hdd_is_5g_supported(pHddCtx))
5221 {
5222 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5223 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305224
5225 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5226 {
5227
5228 if (NULL == wiphy->bands[i])
5229 {
5230 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5231 __func__, i);
5232 continue;
5233 }
5234
5235 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5236 {
5237 struct ieee80211_supported_band *band = wiphy->bands[i];
5238
5239 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5240 {
5241 // Enable social channels for P2P
5242 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5243 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5244 else
5245 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5246 continue;
5247 }
5248 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5249 {
5250 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5251 continue;
5252 }
5253 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 }
5255 /*Initialise the supported cipher suite details*/
5256 wiphy->cipher_suites = hdd_cipher_suites;
5257 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5258
5259 /*signal strength in mBm (100*dBm) */
5260 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5261
5262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305263 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005264#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005265
Sunil Duttc69bccb2014-05-26 21:30:20 +05305266 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
5267 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005268 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
5269 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
5270
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305271 EXIT();
5272 return 0;
5273}
5274
5275/* In this function we are registering wiphy. */
5276int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
5277{
5278 ENTER();
5279 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005280 if (0 > wiphy_register(wiphy))
5281 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305282 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
5284 return -EIO;
5285 }
5286
5287 EXIT();
5288 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289}
Jeff Johnson295189b2012-06-20 16:38:30 -07005290
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305291/* In this function we are updating channel list when,
5292 regulatory domain is FCC and country code is US.
5293 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
5294 As per FCC smart phone is not a indoor device.
5295 GO should not opeate on indoor channels */
5296void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
5297{
5298 int j;
5299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5300 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
5301 //Default counrtycode from NV at the time of wiphy initialization.
5302 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
5303 &defaultCountryCode[0]))
5304 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005305 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305306 }
5307 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
5308 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305309 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
5310 {
5311 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
5312 return;
5313 }
5314 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
5315 {
5316 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
5317 // Mark UNII -1 band channel as passive
5318 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
5319 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
5320 }
5321 }
5322}
5323
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305324/* This function registers for all frame which supplicant is interested in */
5325void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005326{
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5328 /* Register for all P2P action, public action etc frames */
5329 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5330
Jeff Johnsone7245742012-09-05 17:12:55 -07005331 ENTER();
5332
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 /* Right now we are registering these frame when driver is getting
5334 initialized. Once we will move to 2.6.37 kernel, in which we have
5335 frame register ops, we will move this code as a part of that */
5336 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305337 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07005338 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5339
5340 /* GAS Initial Response */
5341 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5342 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305343
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 /* GAS Comeback Request */
5345 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5346 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5347
5348 /* GAS Comeback Response */
5349 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5350 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5351
5352 /* P2P Public Action */
5353 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305354 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 P2P_PUBLIC_ACTION_FRAME_SIZE );
5356
5357 /* P2P Action */
5358 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5359 (v_U8_t*)P2P_ACTION_FRAME,
5360 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07005361
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05305362 /* WNM BSS Transition Request frame */
5363 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5364 (v_U8_t*)WNM_BSS_ACTION_FRAME,
5365 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005366
5367 /* WNM-Notification */
5368 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
5369 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5370 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005371}
5372
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05305373void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07005374{
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5376 /* Register for all P2P action, public action etc frames */
5377 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
5378
Jeff Johnsone7245742012-09-05 17:12:55 -07005379 ENTER();
5380
Jeff Johnson295189b2012-06-20 16:38:30 -07005381 /* Right now we are registering these frame when driver is getting
5382 initialized. Once we will move to 2.6.37 kernel, in which we have
5383 frame register ops, we will move this code as a part of that */
5384 /* GAS Initial Request */
5385
5386 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5387 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
5388
5389 /* GAS Initial Response */
5390 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5391 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305392
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 /* GAS Comeback Request */
5394 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5395 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
5396
5397 /* GAS Comeback Response */
5398 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5399 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
5400
5401 /* P2P Public Action */
5402 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305403 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 P2P_PUBLIC_ACTION_FRAME_SIZE );
5405
5406 /* P2P Action */
5407 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5408 (v_U8_t*)P2P_ACTION_FRAME,
5409 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07005410 /* WNM-Notification */
5411 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
5412 (v_U8_t*)WNM_NOTIFICATION_FRAME,
5413 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07005414}
5415
5416#ifdef FEATURE_WLAN_WAPI
5417void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
5418 const u8 *mac_addr, u8 *key , int key_Len)
5419{
5420 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5421 tCsrRoamSetKey setKey;
5422 v_BOOL_t isConnected = TRUE;
5423 int status = 0;
5424 v_U32_t roamId= 0xFF;
5425 tANI_U8 *pKeyPtr = NULL;
5426 int n = 0;
5427
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
5429 __func__, hdd_device_modetoString(pAdapter->device_mode),
5430 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005431
Gopichand Nakkalae7480202013-02-11 15:24:22 +05305432 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 setKey.keyId = key_index; // Store Key ID
5434 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
5435 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
5436 setKey.paeRole = 0 ; // the PAE role
5437 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
5438 {
5439 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
5440 }
5441 else
5442 {
5443 isConnected = hdd_connIsConnected(pHddStaCtx);
5444 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
5445 }
5446 setKey.keyLength = key_Len;
5447 pKeyPtr = setKey.Key;
5448 memcpy( pKeyPtr, key, key_Len);
5449
Arif Hussain6d2a3322013-11-17 19:50:10 -08005450 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 __func__, key_Len);
5452 for (n = 0 ; n < key_Len; n++)
5453 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
5454 __func__,n,setKey.Key[n]);
5455
5456 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
5457 if ( isConnected )
5458 {
5459 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
5460 pAdapter->sessionId, &setKey, &roamId );
5461 }
5462 if ( status != 0 )
5463 {
5464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5465 "[%4d] sme_RoamSetKey returned ERROR status= %d",
5466 __LINE__, status );
5467 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
5468 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05305469 /* Need to clear any trace of key value in the memory.
5470 * Thus zero out the memory even though it is local
5471 * variable.
5472 */
5473 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07005474}
5475#endif /* FEATURE_WLAN_WAPI*/
5476
5477#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305478int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 beacon_data_t **ppBeacon,
5480 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005481#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005483 beacon_data_t **ppBeacon,
5484 struct cfg80211_beacon_data *params,
5485 int dtim_period)
5486#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487{
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 int size;
5489 beacon_data_t *beacon = NULL;
5490 beacon_data_t *old = NULL;
5491 int head_len,tail_len;
5492
Jeff Johnsone7245742012-09-05 17:12:55 -07005493 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305495 {
5496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5497 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005500
5501 old = pAdapter->sessionCtx.ap.beacon;
5502
5503 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305504 {
5505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5506 FL("session(%d) old and new heads points to NULL"),
5507 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305509 }
5510
5511 if (params->tail && !params->tail_len)
5512 {
5513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5514 FL("tail_len is zero but tail is not NULL"));
5515 return -EINVAL;
5516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005517
Jeff Johnson295189b2012-06-20 16:38:30 -07005518#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
5519 /* Kernel 3.0 is not updating dtim_period for set beacon */
5520 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305521 {
5522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5523 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005526#endif
5527
5528 if(params->head)
5529 head_len = params->head_len;
5530 else
5531 head_len = old->head_len;
5532
5533 if(params->tail || !old)
5534 tail_len = params->tail_len;
5535 else
5536 tail_len = old->tail_len;
5537
5538 size = sizeof(beacon_data_t) + head_len + tail_len;
5539
5540 beacon = kzalloc(size, GFP_KERNEL);
5541
5542 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305543 {
5544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5545 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005548
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005549#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005550 if(params->dtim_period || !old )
5551 beacon->dtim_period = params->dtim_period;
5552 else
5553 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005554#else
5555 if(dtim_period || !old )
5556 beacon->dtim_period = dtim_period;
5557 else
5558 beacon->dtim_period = old->dtim_period;
5559#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305560
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
5562 beacon->tail = beacon->head + head_len;
5563 beacon->head_len = head_len;
5564 beacon->tail_len = tail_len;
5565
5566 if(params->head) {
5567 memcpy (beacon->head,params->head,beacon->head_len);
5568 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305569 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 if(old)
5571 memcpy (beacon->head,old->head,beacon->head_len);
5572 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305573
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 if(params->tail) {
5575 memcpy (beacon->tail,params->tail,beacon->tail_len);
5576 }
5577 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305578 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 memcpy (beacon->tail,old->tail,beacon->tail_len);
5580 }
5581
5582 *ppBeacon = beacon;
5583
5584 kfree(old);
5585
5586 return 0;
5587
5588}
Jeff Johnson295189b2012-06-20 16:38:30 -07005589
5590v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
5591{
5592 int left = length;
5593 v_U8_t *ptr = pIes;
5594 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305595
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305597 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 elem_id = ptr[0];
5599 elem_len = ptr[1];
5600 left -= 2;
5601 if(elem_len > left)
5602 {
5603 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005604 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 eid,elem_len,left);
5606 return NULL;
5607 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 {
5610 return ptr;
5611 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305612
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 left -= elem_len;
5614 ptr += (elem_len + 2);
5615 }
5616 return NULL;
5617}
5618
Jeff Johnson295189b2012-06-20 16:38:30 -07005619/* Check if rate is 11g rate or not */
5620static int wlan_hdd_rate_is_11g(u8 rate)
5621{
Sanjay Devnani28322e22013-06-21 16:13:40 -07005622 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 u8 i;
5624 for (i = 0; i < 8; i++)
5625 {
5626 if(rate == gRateArray[i])
5627 return TRUE;
5628 }
5629 return FALSE;
5630}
5631
5632/* Check for 11g rate and set proper 11g only mode */
5633static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
5634 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
5635{
5636 u8 i, num_rates = pIe[0];
5637
5638 pIe += 1;
5639 for ( i = 0; i < num_rates; i++)
5640 {
5641 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
5642 {
5643 /* If rate set have 11g rate than change the mode to 11G */
5644 *pSapHw_mode = eSAP_DOT11_MODE_11g;
5645 if (pIe[i] & BASIC_RATE_MASK)
5646 {
5647 /* If we have 11g rate as basic rate, it means mode
5648 is 11g only mode.
5649 */
5650 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
5651 *pCheckRatesfor11g = FALSE;
5652 }
5653 }
5654 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
5655 {
5656 *require_ht = TRUE;
5657 }
5658 }
5659 return;
5660}
5661
5662static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
5663{
5664 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5665 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5666 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5667 u8 checkRatesfor11g = TRUE;
5668 u8 require_ht = FALSE;
5669 u8 *pIe=NULL;
5670
5671 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
5672
5673 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
5674 pBeacon->head_len, WLAN_EID_SUPP_RATES);
5675 if (pIe != NULL)
5676 {
5677 pIe += 1;
5678 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5679 &pConfig->SapHw_mode);
5680 }
5681
5682 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5683 WLAN_EID_EXT_SUPP_RATES);
5684 if (pIe != NULL)
5685 {
5686
5687 pIe += 1;
5688 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
5689 &pConfig->SapHw_mode);
5690 }
5691
5692 if( pConfig->channel > 14 )
5693 {
5694 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
5695 }
5696
5697 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
5698 WLAN_EID_HT_CAPABILITY);
5699
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 {
5702 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
5703 if(require_ht)
5704 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
5705 }
5706}
5707
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305708static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
5709 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
5710{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005711 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305712 v_U8_t *pIe = NULL;
5713 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5714
5715 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
5716 pBeacon->tail, pBeacon->tail_len);
5717
5718 if (pIe)
5719 {
5720 ielen = pIe[1] + 2;
5721 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5722 {
5723 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
5724 }
5725 else
5726 {
5727 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
5728 return -EINVAL;
5729 }
5730 *total_ielen += ielen;
5731 }
5732 return 0;
5733}
5734
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005735static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
5736 v_U8_t *genie, v_U8_t *total_ielen)
5737{
5738 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5739 int left = pBeacon->tail_len;
5740 v_U8_t *ptr = pBeacon->tail;
5741 v_U8_t elem_id, elem_len;
5742 v_U16_t ielen = 0;
5743
5744 if ( NULL == ptr || 0 == left )
5745 return;
5746
5747 while (left >= 2)
5748 {
5749 elem_id = ptr[0];
5750 elem_len = ptr[1];
5751 left -= 2;
5752 if (elem_len > left)
5753 {
5754 hddLog( VOS_TRACE_LEVEL_ERROR,
5755 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
5756 elem_id, elem_len, left);
5757 return;
5758 }
5759 if (IE_EID_VENDOR == elem_id)
5760 {
5761 /* skipping the VSIE's which we don't want to include or
5762 * it will be included by existing code
5763 */
5764 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
5765#ifdef WLAN_FEATURE_WFD
5766 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
5767#endif
5768 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5769 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5770 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
5771 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
5772 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
5773 {
5774 ielen = ptr[1] + 2;
5775 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
5776 {
5777 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
5778 *total_ielen += ielen;
5779 }
5780 else
5781 {
5782 hddLog( VOS_TRACE_LEVEL_ERROR,
5783 "IE Length is too big "
5784 "IEs eid=%d elem_len=%d total_ie_lent=%d",
5785 elem_id, elem_len, *total_ielen);
5786 }
5787 }
5788 }
5789
5790 left -= elem_len;
5791 ptr += (elem_len + 2);
5792 }
5793 return;
5794}
5795
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005796#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005797static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5798 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005799#else
5800static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
5801 struct cfg80211_beacon_data *params)
5802#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005803{
5804 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305805 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07005807 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005808
5809 genie = vos_mem_malloc(MAX_GENIE_LEN);
5810
5811 if(genie == NULL) {
5812
5813 return -ENOMEM;
5814 }
5815
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305816 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5817 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305819 hddLog(LOGE,
5820 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305821 ret = -EINVAL;
5822 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 }
5824
5825#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305826 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5827 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
5828 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305829 hddLog(LOGE,
5830 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305831 ret = -EINVAL;
5832 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 }
5834#endif
5835
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305836 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
5837 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305839 hddLog(LOGE,
5840 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305841 ret = -EINVAL;
5842 goto done;
5843 }
5844
5845 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
5846 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07005847 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07005848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005849
5850 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5851 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
5852 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
5853 {
5854 hddLog(LOGE,
5855 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005856 ret = -EINVAL;
5857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 }
5859
5860 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5861 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5862 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5863 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5864 ==eHAL_STATUS_FAILURE)
5865 {
5866 hddLog(LOGE,
5867 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005868 ret = -EINVAL;
5869 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 }
5871
5872 // Added for ProResp IE
5873 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
5874 {
5875 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
5876 u8 probe_rsp_ie_len[3] = {0};
5877 u8 counter = 0;
5878 /* Check Probe Resp Length if it is greater then 255 then Store
5879 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
5880 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
5881 Store More then 255 bytes into One Variable.
5882 */
5883 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5884 {
5885 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5886 {
5887 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5888 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5889 }
5890 else
5891 {
5892 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5893 rem_probe_resp_ie_len = 0;
5894 }
5895 }
5896
5897 rem_probe_resp_ie_len = 0;
5898
5899 if (probe_rsp_ie_len[0] > 0)
5900 {
5901 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5902 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5903 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5904 probe_rsp_ie_len[0], NULL,
5905 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5906 {
5907 hddLog(LOGE,
5908 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005909 ret = -EINVAL;
5910 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 }
5912 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5913 }
5914
5915 if (probe_rsp_ie_len[1] > 0)
5916 {
5917 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5918 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5919 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5920 probe_rsp_ie_len[1], NULL,
5921 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5922 {
5923 hddLog(LOGE,
5924 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005925 ret = -EINVAL;
5926 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 }
5928 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5929 }
5930
5931 if (probe_rsp_ie_len[2] > 0)
5932 {
5933 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5934 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5935 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
5936 probe_rsp_ie_len[2], NULL,
5937 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5938 {
5939 hddLog(LOGE,
5940 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005941 ret = -EINVAL;
5942 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 }
5944 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5945 }
5946
5947 if (probe_rsp_ie_len[1] == 0 )
5948 {
5949 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5950 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
5951 eANI_BOOLEAN_FALSE) )
5952 {
5953 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005954 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 }
5956 }
5957
5958 if (probe_rsp_ie_len[2] == 0 )
5959 {
5960 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5961 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
5962 eANI_BOOLEAN_FALSE) )
5963 {
5964 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 }
5967 }
5968
5969 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5970 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5971 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5972 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5973 == eHAL_STATUS_FAILURE)
5974 {
5975 hddLog(LOGE,
5976 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005977 ret = -EINVAL;
5978 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 }
5980 }
5981 else
5982 {
5983 // Reset WNI_CFG_PROBE_RSP Flags
5984 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5985
5986 hddLog(VOS_TRACE_LEVEL_INFO,
5987 "%s: No Probe Response IE received in set beacon",
5988 __func__);
5989 }
5990
5991 // Added for AssocResp IE
5992 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5993 {
5994 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5995 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5996 params->assocresp_ies_len, NULL,
5997 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5998 {
5999 hddLog(LOGE,
6000 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006001 ret = -EINVAL;
6002 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 }
6004
6005 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6006 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6007 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6008 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6009 == eHAL_STATUS_FAILURE)
6010 {
6011 hddLog(LOGE,
6012 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006013 ret = -EINVAL;
6014 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 }
6016 }
6017 else
6018 {
6019 hddLog(VOS_TRACE_LEVEL_INFO,
6020 "%s: No Assoc Response IE received in set beacon",
6021 __func__);
6022
6023 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6024 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6025 eANI_BOOLEAN_FALSE) )
6026 {
6027 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006028 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 }
6030 }
6031
Jeff Johnsone7245742012-09-05 17:12:55 -07006032done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306034 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006035}
Jeff Johnson295189b2012-06-20 16:38:30 -07006036
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 * FUNCTION: wlan_hdd_validate_operation_channel
6039 * called by wlan_hdd_cfg80211_start_bss() and
6040 * wlan_hdd_cfg80211_set_channel()
6041 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306042 * channel list.
6043 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006044VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006045{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 v_U32_t num_ch = 0;
6048 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6049 u32 indx = 0;
6050 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306051 v_U8_t fValidChannel = FALSE, count = 0;
6052 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306053
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6055
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306056 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306058 /* Validate the channel */
6059 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306061 if ( channel == rfChannels[count].channelNum )
6062 {
6063 fValidChannel = TRUE;
6064 break;
6065 }
6066 }
6067 if (fValidChannel != TRUE)
6068 {
6069 hddLog(VOS_TRACE_LEVEL_ERROR,
6070 "%s: Invalid Channel [%d]", __func__, channel);
6071 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 }
6073 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306074 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306076 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6077 valid_ch, &num_ch))
6078 {
6079 hddLog(VOS_TRACE_LEVEL_ERROR,
6080 "%s: failed to get valid channel list", __func__);
6081 return VOS_STATUS_E_FAILURE;
6082 }
6083 for (indx = 0; indx < num_ch; indx++)
6084 {
6085 if (channel == valid_ch[indx])
6086 {
6087 break;
6088 }
6089 }
6090
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306091 if (indx >= num_ch)
6092 {
6093 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6094 {
6095 eCsrBand band;
6096 unsigned int freq;
6097
6098 sme_GetFreqBand(hHal, &band);
6099
6100 if (eCSR_BAND_5G == band)
6101 {
6102#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6103 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6104 {
6105 freq = ieee80211_channel_to_frequency(channel,
6106 IEEE80211_BAND_2GHZ);
6107 }
6108 else
6109 {
6110 freq = ieee80211_channel_to_frequency(channel,
6111 IEEE80211_BAND_5GHZ);
6112 }
6113#else
6114 freq = ieee80211_channel_to_frequency(channel);
6115#endif
6116 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6117 return VOS_STATUS_SUCCESS;
6118 }
6119 }
6120
6121 hddLog(VOS_TRACE_LEVEL_ERROR,
6122 "%s: Invalid Channel [%d]", __func__, channel);
6123 return VOS_STATUS_E_FAILURE;
6124 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128
Jeff Johnson295189b2012-06-20 16:38:30 -07006129}
6130
Viral Modi3a32cc52013-02-08 11:14:52 -08006131/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306132 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006133 * This function is used to set the channel number
6134 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306135static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006136 struct ieee80211_channel *chan,
6137 enum nl80211_channel_type channel_type
6138 )
6139{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306140 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006141 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006142 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006143 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306144 hdd_context_t *pHddCtx;
6145 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006146
6147 ENTER();
6148
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306149
Viral Modi3a32cc52013-02-08 11:14:52 -08006150 if( NULL == dev )
6151 {
6152 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006153 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006154 return -ENODEV;
6155 }
6156 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6159 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6160 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006161 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306162 "%s: device_mode = %s (%d) freq = %d", __func__,
6163 hdd_device_modetoString(pAdapter->device_mode),
6164 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306165
6166 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6167 status = wlan_hdd_validate_context(pHddCtx);
6168
6169 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006170 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6172 "%s: HDD context is not valid", __func__);
6173 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006174 }
6175
6176 /*
6177 * Do freq to chan conversion
6178 * TODO: for 11a
6179 */
6180
6181 channel = ieee80211_frequency_to_channel(freq);
6182
6183 /* Check freq range */
6184 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6185 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6186 {
6187 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006188 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006189 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6190 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6191 return -EINVAL;
6192 }
6193
6194 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6195
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306196 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6197 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006198 {
6199 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6200 {
6201 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006202 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006203 return -EINVAL;
6204 }
6205 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6206 "%s: set channel to [%d] for device mode =%d",
6207 __func__, channel,pAdapter->device_mode);
6208 }
6209 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006210 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006211 )
6212 {
6213 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6214 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6215 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6216
6217 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6218 {
6219 /* Link is up then return cant set channel*/
6220 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006221 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006222 return -EINVAL;
6223 }
6224
6225 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6226 pHddStaCtx->conn_info.operationChannel = channel;
6227 pRoamProfile->ChannelInfo.ChannelList =
6228 &pHddStaCtx->conn_info.operationChannel;
6229 }
6230 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006231 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006232 )
6233 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306234 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6235 {
6236 if(VOS_STATUS_SUCCESS !=
6237 wlan_hdd_validate_operation_channel(pAdapter,channel))
6238 {
6239 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006240 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306241 return -EINVAL;
6242 }
6243 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6244 }
6245 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006246 {
6247 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6248
6249 /* If auto channel selection is configured as enable/ 1 then ignore
6250 channel set by supplicant
6251 */
6252 if ( cfg_param->apAutoChannelSelection )
6253 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306254 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6255 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006256 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306257 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6258 __func__, hdd_device_modetoString(pAdapter->device_mode),
6259 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006260 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306261 else
6262 {
6263 if(VOS_STATUS_SUCCESS !=
6264 wlan_hdd_validate_operation_channel(pAdapter,channel))
6265 {
6266 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006267 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306268 return -EINVAL;
6269 }
6270 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6271 }
Viral Modi3a32cc52013-02-08 11:14:52 -08006272 }
6273 }
6274 else
6275 {
6276 hddLog(VOS_TRACE_LEVEL_FATAL,
6277 "%s: Invalid device mode failed to set valid channel", __func__);
6278 return -EINVAL;
6279 }
6280 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306281 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006282}
6283
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306284static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
6285 struct net_device *dev,
6286 struct ieee80211_channel *chan,
6287 enum nl80211_channel_type channel_type
6288 )
6289{
6290 int ret;
6291
6292 vos_ssr_protect(__func__);
6293 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
6294 vos_ssr_unprotect(__func__);
6295
6296 return ret;
6297}
6298
Jeff Johnson295189b2012-06-20 16:38:30 -07006299#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6300static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6301 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006302#else
6303static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
6304 struct cfg80211_beacon_data *params,
6305 const u8 *ssid, size_t ssid_len,
6306 enum nl80211_hidden_ssid hidden_ssid)
6307#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006308{
6309 tsap_Config_t *pConfig;
6310 beacon_data_t *pBeacon = NULL;
6311 struct ieee80211_mgmt *pMgmt_frame;
6312 v_U8_t *pIe=NULL;
6313 v_U16_t capab_info;
6314 eCsrAuthType RSNAuthType;
6315 eCsrEncryptionType RSNEncryptType;
6316 eCsrEncryptionType mcRSNEncryptType;
6317 int status = VOS_STATUS_SUCCESS;
6318 tpWLAN_SAPEventCB pSapEventCallback;
6319 hdd_hostapd_state_t *pHostapdState;
6320 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
6321 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306322 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306324 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08006326 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05306327 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07006328 v_BOOL_t MFPCapable = VOS_FALSE;
6329 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306330 eHddDot11Mode sapDot11Mode =
6331 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332
6333 ENTER();
6334
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306335 iniConfig = pHddCtx->cfg_ini;
6336
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
6338
6339 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6340
6341 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6342
6343 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6344
6345 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
6346
6347 //channel is already set in the set_channel Call back
6348 //pConfig->channel = pCommitConfig->channel;
6349
6350 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306351 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
6353
6354 pConfig->dtim_period = pBeacon->dtim_period;
6355
Arif Hussain6d2a3322013-11-17 19:50:10 -08006356 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 pConfig->dtim_period);
6358
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08006359 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07006360 {
6361 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05306363 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
6364 {
6365 tANI_BOOLEAN restartNeeded;
6366 pConfig->ieee80211d = 1;
6367 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
6368 sme_setRegInfo(hHal, pConfig->countryCode);
6369 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
6370 }
6371 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07006373 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07006374 pConfig->ieee80211d = 1;
6375 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
6376 sme_setRegInfo(hHal, pConfig->countryCode);
6377 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006379 else
6380 {
6381 pConfig->ieee80211d = 0;
6382 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306383 /*
6384 * If auto channel is configured i.e. channel is 0,
6385 * so skip channel validation.
6386 */
6387 if( AUTO_CHANNEL_SELECT != pConfig->channel )
6388 {
6389 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006392 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05306393 return -EINVAL;
6394 }
6395 }
6396 else
6397 {
6398 if(1 != pHddCtx->is_dynamic_channel_range_set)
6399 {
6400 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
6401 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
6402 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
6403 }
6404 pHddCtx->is_dynamic_channel_range_set = 0;
6405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006407 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 {
6409 pConfig->ieee80211d = 0;
6410 }
6411 pConfig->authType = eSAP_AUTO_SWITCH;
6412
6413 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414
6415 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
6417
6418 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
6419
6420 /*Set wps station to configured*/
6421 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
6422
6423 if(pIe)
6424 {
6425 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
6426 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006427 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 return -EINVAL;
6429 }
6430 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
6431 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006432 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 /* Check 15 bit of WPS IE as it contain information for wps state
6434 * WPS state
6435 */
6436 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
6437 {
6438 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
6439 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
6440 {
6441 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6442 }
6443 }
6444 }
6445 else
6446 {
6447 pConfig->wps_state = SAP_WPS_DISABLED;
6448 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306449 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07006450
c_hpothufe599e92014-06-16 11:38:55 +05306451 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6452 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
6453 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
6454 eCSR_ENCRYPT_TYPE_NONE;
6455
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 pConfig->RSNWPAReqIELength = 0;
6457 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 WLAN_EID_RSN);
6460 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6463 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6464 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306465 /* The actual processing may eventually be more extensive than
6466 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 * by the app.
6468 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306469 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6471 &RSNEncryptType,
6472 &mcRSNEncryptType,
6473 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006474 &MFPCapable,
6475 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 pConfig->pRSNWPAReqIE[1]+2,
6477 pConfig->pRSNWPAReqIE );
6478
6479 if( VOS_STATUS_SUCCESS == status )
6480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306481 /* Now copy over all the security attributes you have
6482 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 * */
6484 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6485 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6486 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6487 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306488 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006489 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6491 }
6492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306493
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6495 pBeacon->tail, pBeacon->tail_len);
6496
6497 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
6498 {
6499 if (pConfig->pRSNWPAReqIE)
6500 {
6501 /*Mixed mode WPA/WPA2*/
6502 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
6503 pConfig->RSNWPAReqIELength += pIe[1] + 2;
6504 }
6505 else
6506 {
6507 pConfig->RSNWPAReqIELength = pIe[1] + 2;
6508 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
6509 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306510 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
6512 &RSNEncryptType,
6513 &mcRSNEncryptType,
6514 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08006515 &MFPCapable,
6516 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 pConfig->pRSNWPAReqIE[1]+2,
6518 pConfig->pRSNWPAReqIE );
6519
6520 if( VOS_STATUS_SUCCESS == status )
6521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306522 /* Now copy over all the security attributes you have
6523 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07006524 * */
6525 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
6526 pConfig->mcRSNEncryptType = mcRSNEncryptType;
6527 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
6528 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306529 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08006530 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
6532 }
6533 }
6534 }
6535
Jeff Johnson4416a782013-03-25 14:17:50 -07006536 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
6537 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
6538 return -EINVAL;
6539 }
6540
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
6542
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006543#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 if (params->ssid != NULL)
6545 {
6546 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
6547 pConfig->SSIDinfo.ssid.length = params->ssid_len;
6548 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6549 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6550 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006551#else
6552 if (ssid != NULL)
6553 {
6554 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
6555 pConfig->SSIDinfo.ssid.length = ssid_len;
6556 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
6557 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
6558 }
6559#endif
6560
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306561 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306563
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 /* default value */
6565 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6566 pConfig->num_accept_mac = 0;
6567 pConfig->num_deny_mac = 0;
6568
6569 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6570 pBeacon->tail, pBeacon->tail_len);
6571
6572 /* pIe for black list is following form:
6573 type : 1 byte
6574 length : 1 byte
6575 OUI : 4 bytes
6576 acl type : 1 byte
6577 no of mac addr in black list: 1 byte
6578 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306579 */
6580 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 {
6582 pConfig->SapMacaddr_acl = pIe[6];
6583 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006584 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306586 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
6587 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6589 for (i = 0; i < pConfig->num_deny_mac; i++)
6590 {
6591 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6592 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 }
6595 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6596 pBeacon->tail, pBeacon->tail_len);
6597
6598 /* pIe for white list is following form:
6599 type : 1 byte
6600 length : 1 byte
6601 OUI : 4 bytes
6602 acl type : 1 byte
6603 no of mac addr in white list: 1 byte
6604 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306605 */
6606 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 {
6608 pConfig->SapMacaddr_acl = pIe[6];
6609 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08006610 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306612 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
6613 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
6615 for (i = 0; i < pConfig->num_accept_mac; i++)
6616 {
6617 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
6618 acl_entry++;
6619 }
6620 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306621
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 wlan_hdd_set_sapHwmode(pHostapdAdapter);
6623
Jeff Johnsone7245742012-09-05 17:12:55 -07006624#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006625 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05306626 * This is valid only if mode is set to 11n in hostapd, either AUTO or
6627 * 11ac in .ini and 11ac is supported by both host and firmware.
6628 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
6629 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08006630 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
6631 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05306632 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
6633 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
6634 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
6635 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
6636 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07006637 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306638 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07006639 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306640 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006641
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306642 /* If ACS disable and selected channel <= 14
6643 * OR
6644 * ACS enabled and ACS operating band is choosen as 2.4
6645 * AND
6646 * VHT in 2.4G Disabled
6647 * THEN
6648 * Fallback to 11N mode
6649 */
6650 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
6651 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05306652 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05306653 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006654 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05306655 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
6656 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07006657 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
6658 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006659 }
6660#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306661
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 // ht_capab is not what the name conveys,this is used for protection bitmap
6663 pConfig->ht_capab =
6664 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
6665
6666 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
6667 {
6668 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
6669 return -EINVAL;
6670 }
6671
6672 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306673 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
6675 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306676 pConfig->obssProtEnabled =
6677 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07006678
Chet Lanctot8cecea22014-02-11 19:09:36 -08006679#ifdef WLAN_FEATURE_11W
6680 pConfig->mfpCapable = MFPCapable;
6681 pConfig->mfpRequired = MFPRequired;
6682 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
6683 pConfig->mfpCapable, pConfig->mfpRequired);
6684#endif
6685
Arif Hussain6d2a3322013-11-17 19:50:10 -08006686 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006688 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
6689 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
6690 (int)pConfig->channel);
6691 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
6692 pConfig->SapHw_mode, pConfig->privacy,
6693 pConfig->authType);
6694 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
6695 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
6696 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
6697 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07006698
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306699 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 {
6701 //Bss already started. just return.
6702 //TODO Probably it should update some beacon params.
6703 hddLog( LOGE, "Bss Already started...Ignore the request");
6704 EXIT();
6705 return 0;
6706 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306707
Agarwal Ashish51325b52014-06-16 16:50:49 +05306708 if (vos_max_concurrent_connections_reached()) {
6709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6710 return -EINVAL;
6711 }
6712
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 pConfig->persona = pHostapdAdapter->device_mode;
6714
Peng Xu2446a892014-09-05 17:21:18 +05306715 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
6716 if ( NULL != psmeConfig)
6717 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306718 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05306719 sme_GetConfigParam(hHal, psmeConfig);
6720 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05306721#ifdef WLAN_FEATURE_AP_HT40_24G
6722 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
6723 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
6724 && pHddCtx->cfg_ini->apHT40_24GEnabled)
6725 {
6726 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
6727 sme_UpdateConfig (hHal, psmeConfig);
6728 }
6729#endif
Peng Xu2446a892014-09-05 17:21:18 +05306730 vos_mem_free(psmeConfig);
6731 }
Peng Xuafc34e32014-09-25 13:23:55 +05306732 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05306733
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 pSapEventCallback = hdd_hostapd_SAPEventCB;
6735 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
6736 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
6737 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006738 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 return -EINVAL;
6740 }
6741
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306742 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
6744
6745 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306746
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306748 {
6749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006750 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07006751 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 VOS_ASSERT(0);
6753 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306754
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05306756 /* Initialize WMM configuation */
6757 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306758 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006759
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006760#ifdef WLAN_FEATURE_P2P_DEBUG
6761 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
6762 {
6763 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
6764 {
6765 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6766 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006767 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006768 }
6769 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
6770 {
6771 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
6772 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08006773 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006774 }
6775 }
6776#endif
6777
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 pHostapdState->bCommit = TRUE;
6779 EXIT();
6780
6781 return 0;
6782}
6783
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006784#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306785static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 struct beacon_parameters *params)
6788{
6789 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306790 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306791 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006792
6793 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306794
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306795 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6796 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
6797 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306798 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
6799 hdd_device_modetoString(pAdapter->device_mode),
6800 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006801
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6803 status = wlan_hdd_validate_context(pHddCtx);
6804
6805 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006806 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6808 "%s: HDD context is not valid", __func__);
6809 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006810 }
6811
Agarwal Ashish51325b52014-06-16 16:50:49 +05306812 if (vos_max_concurrent_connections_reached()) {
6813 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6814 return -EINVAL;
6815 }
6816
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306817 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 )
6820 {
6821 beacon_data_t *old,*new;
6822
6823 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306824
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306826 {
6827 hddLog(VOS_TRACE_LEVEL_WARN,
6828 FL("already beacon info added to session(%d)"),
6829 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006832
6833 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6834
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306835 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 {
6837 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006838 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006839 return -EINVAL;
6840 }
6841
6842 pAdapter->sessionCtx.ap.beacon = new;
6843
6844 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6845 }
6846
6847 EXIT();
6848 return status;
6849}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306850
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306851static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
6852 struct net_device *dev,
6853 struct beacon_parameters *params)
6854{
6855 int ret;
6856
6857 vos_ssr_protect(__func__);
6858 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
6859 vos_ssr_unprotect(__func__);
6860
6861 return ret;
6862}
6863
6864static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 struct net_device *dev,
6866 struct beacon_parameters *params)
6867{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306869 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6870 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306871 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006872
6873 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306874 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6875 TRACE_CODE_HDD_CFG80211_SET_BEACON,
6876 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
6877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6878 __func__, hdd_device_modetoString(pAdapter->device_mode),
6879 pAdapter->device_mode);
6880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6882 status = wlan_hdd_validate_context(pHddCtx);
6883
6884 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006885 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6887 "%s: HDD context is not valid", __func__);
6888 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006889 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306890
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306891 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306893 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 {
6895 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306896
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306900 {
6901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6902 FL("session(%d) old and new heads points to NULL"),
6903 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006906
6907 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
6908
6909 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006911 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 return -EINVAL;
6913 }
6914
6915 pAdapter->sessionCtx.ap.beacon = new;
6916
6917 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
6918 }
6919
6920 EXIT();
6921 return status;
6922}
6923
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306924static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
6925 struct net_device *dev,
6926 struct beacon_parameters *params)
6927{
6928 int ret;
6929
6930 vos_ssr_protect(__func__);
6931 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
6932 vos_ssr_unprotect(__func__);
6933
6934 return ret;
6935}
6936
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006937#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
6938
6939#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306940static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006942#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05306943static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006944 struct net_device *dev)
6945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006946{
6947 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07006948 hdd_context_t *pHddCtx = NULL;
6949 hdd_scaninfo_t *pScanInfo = NULL;
6950 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306951 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306952 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006953
6954 ENTER();
6955
6956 if (NULL == pAdapter)
6957 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006959 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 return -ENODEV;
6961 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006962
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306963 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6964 TRACE_CODE_HDD_CFG80211_STOP_AP,
6965 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6967 status = wlan_hdd_validate_context(pHddCtx);
6968
6969 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006970 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6972 "%s: HDD context is not valid", __func__);
6973 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07006974 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006975
6976 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
6977 if (NULL == staAdapter)
6978 {
6979 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
6980 if (NULL == staAdapter)
6981 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07006982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6983 "%s: HDD adapter context for STA/P2P-CLI is Null",
6984 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006985 }
6986 }
6987
6988 pScanInfo = &pHddCtx->scan_info;
6989
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306990 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6991 __func__, hdd_device_modetoString(pAdapter->device_mode),
6992 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006993
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306994 ret = wlan_hdd_scan_abort(pAdapter);
6995
Girish Gowli4bf7a632014-06-12 13:42:11 +05306996 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07006997 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05306998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6999 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307000
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307001 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007002 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7004 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007005
Jeff Johnsone7245742012-09-05 17:12:55 -07007006 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307007 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007008 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307009 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007010 }
7011
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307012 /* Delete all associated STAs before stopping AP/P2P GO */
7013 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307014 hdd_hostapd_stop(dev);
7015
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 )
7019 {
7020 beacon_data_t *old;
7021
7022 old = pAdapter->sessionCtx.ap.beacon;
7023
7024 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307025 {
7026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7027 FL("session(%d) beacon data points to NULL"),
7028 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007031
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007033
7034 mutex_lock(&pHddCtx->sap_lock);
7035 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7036 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007037 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 {
7039 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7040
7041 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7042
7043 if (!VOS_IS_STATUS_SUCCESS(status))
7044 {
7045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007046 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307048 }
7049 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307051 /* BSS stopped, clear the active sessions for this device mode */
7052 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 }
7054 mutex_unlock(&pHddCtx->sap_lock);
7055
7056 if(status != VOS_STATUS_SUCCESS)
7057 {
7058 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007059 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 return -EINVAL;
7061 }
7062
Jeff Johnson4416a782013-03-25 14:17:50 -07007063 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7065 ==eHAL_STATUS_FAILURE)
7066 {
7067 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007068 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 }
7070
Jeff Johnson4416a782013-03-25 14:17:50 -07007071 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7073 eANI_BOOLEAN_FALSE) )
7074 {
7075 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007076 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 }
7078
7079 // Reset WNI_CFG_PROBE_RSP Flags
7080 wlan_hdd_reset_prob_rspies(pAdapter);
7081
7082 pAdapter->sessionCtx.ap.beacon = NULL;
7083 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007084#ifdef WLAN_FEATURE_P2P_DEBUG
7085 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7086 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7087 {
7088 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7089 "GO got removed");
7090 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7091 }
7092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 }
7094 EXIT();
7095 return status;
7096}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007097
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307098#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7099static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7100 struct net_device *dev)
7101{
7102 int ret;
7103
7104 vos_ssr_protect(__func__);
7105 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7106 vos_ssr_unprotect(__func__);
7107
7108 return ret;
7109}
7110#else
7111static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7112 struct net_device *dev)
7113{
7114 int ret;
7115
7116 vos_ssr_protect(__func__);
7117 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7118 vos_ssr_unprotect(__func__);
7119
7120 return ret;
7121}
7122#endif
7123
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007124#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7125
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307126static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307127 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007128 struct cfg80211_ap_settings *params)
7129{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307130 hdd_adapter_t *pAdapter;
7131 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307132 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007133
7134 ENTER();
7135
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307136 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007137 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307139 "%s: Device is Null", __func__);
7140 return -ENODEV;
7141 }
7142
7143 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7144 if (NULL == pAdapter)
7145 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307147 "%s: HDD adapter is Null", __func__);
7148 return -ENODEV;
7149 }
7150
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307151 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7152 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7153 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307154 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7155 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307157 "%s: HDD adapter magic is invalid", __func__);
7158 return -ENODEV;
7159 }
7160
7161 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307162 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307163
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307164 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307165 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7167 "%s: HDD context is not valid", __func__);
7168 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307169 }
7170
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307171 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7172 __func__, hdd_device_modetoString(pAdapter->device_mode),
7173 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307174
7175 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007176 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007177 )
7178 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307179 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007180
7181 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307182
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007183 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307184 {
7185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7186 FL("already beacon info added to session(%d)"),
7187 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007188 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307189 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007190
7191 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
7192
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307193 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007194 {
7195 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307196 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007197 return -EINVAL;
7198 }
7199 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007201 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7202#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7203 params->channel, params->channel_type);
7204#else
7205 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7206#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007207#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007208 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
7209 params->ssid_len, params->hidden_ssid);
7210 }
7211
7212 EXIT();
7213 return status;
7214}
7215
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307216static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7217 struct net_device *dev,
7218 struct cfg80211_ap_settings *params)
7219{
7220 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007221
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307222 vos_ssr_protect(__func__);
7223 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7224 vos_ssr_unprotect(__func__);
7225
7226 return ret;
7227}
7228
7229static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007230 struct net_device *dev,
7231 struct cfg80211_beacon_data *params)
7232{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307233 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307234 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307235 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007236
7237 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307238
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307239 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7240 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7241 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007243 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307244
7245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7246 status = wlan_hdd_validate_context(pHddCtx);
7247
7248 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7251 "%s: HDD context is not valid", __func__);
7252 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007253 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007254
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307255 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007256 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307257 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007258 {
7259 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307260
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007261 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307262
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007263 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307264 {
7265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7266 FL("session(%d) beacon data points to NULL"),
7267 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007268 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307269 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007270
7271 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
7272
7273 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307274 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007275 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007276 return -EINVAL;
7277 }
7278
7279 pAdapter->sessionCtx.ap.beacon = new;
7280
7281 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
7282 }
7283
7284 EXIT();
7285 return status;
7286}
7287
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307288static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
7289 struct net_device *dev,
7290 struct cfg80211_beacon_data *params)
7291{
7292 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007293
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307294 vos_ssr_protect(__func__);
7295 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
7296 vos_ssr_unprotect(__func__);
7297
7298 return ret;
7299}
7300
7301#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007302
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307303static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 struct net_device *dev,
7305 struct bss_parameters *params)
7306{
7307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307308 hdd_context_t *pHddCtx;
7309 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007310
7311 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307312
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05307313 if (NULL == pAdapter)
7314 {
7315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "%s: HDD adapter is Null", __func__);
7317 return -ENODEV;
7318 }
7319 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7320
7321 ret = wlan_hdd_validate_context(pHddCtx);
7322 if (0 != ret)
7323 {
7324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7325 "%s: HDD context is not valid", __func__);
7326 return ret;
7327 }
7328
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7330 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
7331 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307332 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7333 __func__, hdd_device_modetoString(pAdapter->device_mode),
7334 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007335
7336 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307338 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 {
7340 /* ap_isolate == -1 means that in change bss, upper layer doesn't
7341 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307342 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 {
7344 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307345 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 }
7347
7348 EXIT();
7349 return 0;
7350}
7351
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05307352static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
7353 struct net_device *dev,
7354 struct bss_parameters *params)
7355{
7356 int ret;
7357
7358 vos_ssr_protect(__func__);
7359 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
7360 vos_ssr_unprotect(__func__);
7361
7362 return ret;
7363}
Kiet Lam10841362013-11-01 11:36:50 +05307364/* FUNCTION: wlan_hdd_change_country_code_cd
7365* to wait for contry code completion
7366*/
7367void* wlan_hdd_change_country_code_cb(void *pAdapter)
7368{
7369 hdd_adapter_t *call_back_pAdapter = pAdapter;
7370 complete(&call_back_pAdapter->change_country_code);
7371 return NULL;
7372}
7373
Jeff Johnson295189b2012-06-20 16:38:30 -07007374/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307375 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
7377 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307378int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 struct net_device *ndev,
7380 enum nl80211_iftype type,
7381 u32 *flags,
7382 struct vif_params *params
7383 )
7384{
7385 struct wireless_dev *wdev;
7386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007387 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07007388 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 tCsrRoamProfile *pRoamProfile = NULL;
7390 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307391 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 eMib_dot11DesiredBssType connectedBssType;
7393 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307394 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007395
7396 ENTER();
7397
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307398 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007399 {
7400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7401 "%s: Adapter context is null", __func__);
7402 return VOS_STATUS_E_FAILURE;
7403 }
7404
7405 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7406 if (!pHddCtx)
7407 {
7408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7409 "%s: HDD context is null", __func__);
7410 return VOS_STATUS_E_FAILURE;
7411 }
7412
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307413 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7414 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
7415 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307416 status = wlan_hdd_validate_context(pHddCtx);
7417
7418 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007419 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7421 "%s: HDD context is not valid", __func__);
7422 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 }
7424
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307425 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7426 __func__, hdd_device_modetoString(pAdapter->device_mode),
7427 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007428
Agarwal Ashish51325b52014-06-16 16:50:49 +05307429 if (vos_max_concurrent_connections_reached()) {
7430 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7431 return -EINVAL;
7432 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307433 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 wdev = ndev->ieee80211_ptr;
7435
7436#ifdef WLAN_BTAMP_FEATURE
7437 if((NL80211_IFTYPE_P2P_CLIENT == type)||
7438 (NL80211_IFTYPE_ADHOC == type)||
7439 (NL80211_IFTYPE_AP == type)||
7440 (NL80211_IFTYPE_P2P_GO == type))
7441 {
7442 pHddCtx->isAmpAllowed = VOS_FALSE;
7443 // stop AMP traffic
7444 status = WLANBAP_StopAmp();
7445 if(VOS_STATUS_SUCCESS != status )
7446 {
7447 pHddCtx->isAmpAllowed = VOS_TRUE;
7448 hddLog(VOS_TRACE_LEVEL_FATAL,
7449 "%s: Failed to stop AMP", __func__);
7450 return -EINVAL;
7451 }
7452 }
7453#endif //WLAN_BTAMP_FEATURE
7454 /* Reset the current device mode bit mask*/
7455 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7456
7457 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07007459 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 )
7461 {
7462 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08007463 if (!pWextState)
7464 {
7465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7466 "%s: pWextState is null", __func__);
7467 return VOS_STATUS_E_FAILURE;
7468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 pRoamProfile = &pWextState->roamProfile;
7470 LastBSSType = pRoamProfile->BSSType;
7471
7472 switch (type)
7473 {
7474 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007475 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 hddLog(VOS_TRACE_LEVEL_INFO,
7477 "%s: setting interface Type to INFRASTRUCTURE", __func__);
7478 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07007479#ifdef WLAN_FEATURE_11AC
7480 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
7481 {
7482 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
7483 }
7484#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307485 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07007486 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007488 //Check for sub-string p2p to confirm its a p2p interface
7489 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307490 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007491 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7492 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7493 }
7494 else
7495 {
7496 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007498 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05307500
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 case NL80211_IFTYPE_ADHOC:
7502 hddLog(VOS_TRACE_LEVEL_INFO,
7503 "%s: setting interface Type to ADHOC", __func__);
7504 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
7505 pRoamProfile->phyMode =
7506 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07007507 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 wdev->iftype = type;
7509 break;
7510
7511 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007513 {
7514 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7515 "%s: setting interface Type to %s", __func__,
7516 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
7517
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007518 //Cancel any remain on channel for GO mode
7519 if (NL80211_IFTYPE_P2P_GO == type)
7520 {
7521 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
7522 }
Mohit Khanna0f232092012-09-11 14:46:08 -07007523 if (NL80211_IFTYPE_AP == type)
7524 {
7525 /* As Loading WLAN Driver one interface being created for p2p device
7526 * address. This will take one HW STA and the max number of clients
7527 * that can connect to softAP will be reduced by one. so while changing
7528 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
7529 * interface as it is not required in SoftAP mode.
7530 */
7531
7532 // Get P2P Adapter
7533 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
7534
7535 if (pP2pAdapter)
7536 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307537 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05307538 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07007539 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
7540 }
7541 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05307542 //Disable IMPS & BMPS for SAP/GO
7543 if(VOS_STATUS_E_FAILURE ==
7544 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
7545 {
7546 //Fail to Exit BMPS
7547 VOS_ASSERT(0);
7548 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05307549
7550 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
7551
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307552#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07007553
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307554 /* A Mutex Lock is introduced while changing the mode to
7555 * protect the concurrent access for the Adapters by TDLS
7556 * module.
7557 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307558 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05307561 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7564 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307565#ifdef FEATURE_WLAN_TDLS
7566 mutex_unlock(&pHddCtx->tdls_lock);
7567#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007568 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
7569 (pConfig->apRandomBssidEnabled))
7570 {
7571 /* To meet Android requirements create a randomized
7572 MAC address of the form 02:1A:11:Fx:xx:xx */
7573 get_random_bytes(&ndev->dev_addr[3], 3);
7574 ndev->dev_addr[0] = 0x02;
7575 ndev->dev_addr[1] = 0x1A;
7576 ndev->dev_addr[2] = 0x11;
7577 ndev->dev_addr[3] |= 0xF0;
7578 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
7579 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08007580 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
7581 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07007582 }
7583
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 hdd_set_ap_ops( pAdapter->dev );
7585
Kiet Lam10841362013-11-01 11:36:50 +05307586 /* This is for only SAP mode where users can
7587 * control country through ini.
7588 * P2P GO follows station country code
7589 * acquired during the STA scanning. */
7590 if((NL80211_IFTYPE_AP == type) &&
7591 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
7592 {
7593 int status = 0;
7594 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
7595 "%s: setting country code from INI ", __func__);
7596 init_completion(&pAdapter->change_country_code);
7597 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
7598 (void *)(tSmeChangeCountryCallback)
7599 wlan_hdd_change_country_code_cb,
7600 pConfig->apCntryCode, pAdapter,
7601 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05307602 eSIR_FALSE,
7603 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05307604 if (eHAL_STATUS_SUCCESS == status)
7605 {
7606 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307607 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05307608 &pAdapter->change_country_code,
7609 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307610 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05307611 {
7612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307613 FL("SME Timed out while setting country code %ld"),
7614 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08007615
7616 if (pHddCtx->isLogpInProgress)
7617 {
7618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7619 "%s: LOGP in Progress. Ignore!!!", __func__);
7620 return -EAGAIN;
7621 }
Kiet Lam10841362013-11-01 11:36:50 +05307622 }
7623 }
7624 else
7625 {
7626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007627 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05307628 return -EINVAL;
7629 }
7630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 status = hdd_init_ap_mode(pAdapter);
7632 if(status != VOS_STATUS_SUCCESS)
7633 {
7634 hddLog(VOS_TRACE_LEVEL_FATAL,
7635 "%s: Error initializing the ap mode", __func__);
7636 return -EINVAL;
7637 }
7638 hdd_set_conparam(1);
7639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 /*interface type changed update in wiphy structure*/
7641 if(wdev)
7642 {
7643 wdev->iftype = type;
7644 pHddCtx->change_iface = type;
7645 }
7646 else
7647 {
7648 hddLog(VOS_TRACE_LEVEL_ERROR,
7649 "%s: ERROR !!!! Wireless dev is NULL", __func__);
7650 return -EINVAL;
7651 }
7652 goto done;
7653 }
7654
7655 default:
7656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7657 __func__);
7658 return -EOPNOTSUPP;
7659 }
7660 }
7661 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 )
7664 {
7665 switch(type)
7666 {
7667 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05307670
7671 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307672#ifdef FEATURE_WLAN_TDLS
7673
7674 /* A Mutex Lock is introduced while changing the mode to
7675 * protect the concurrent access for the Adapters by TDLS
7676 * module.
7677 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307678 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307679#endif
c_hpothu002231a2015-02-05 14:58:51 +05307680 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08007682 //Check for sub-string p2p to confirm its a p2p interface
7683 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007684 {
7685 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
7686 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
7687 }
7688 else
7689 {
7690 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08007692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 hdd_set_conparam(0);
7694 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
7696 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307697#ifdef FEATURE_WLAN_TDLS
7698 mutex_unlock(&pHddCtx->tdls_lock);
7699#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307700 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 if( VOS_STATUS_SUCCESS != status )
7702 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07007703 /* In case of JB, for P2P-GO, only change interface will be called,
7704 * This is the right place to enable back bmps_imps()
7705 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307706 if (pHddCtx->hdd_wlan_suspended)
7707 {
7708 hdd_set_pwrparams(pHddCtx);
7709 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007710 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007711 goto done;
7712 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
7716 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 goto done;
7718 default:
7719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
7720 __func__);
7721 return -EOPNOTSUPP;
7722
7723 }
7724
7725 }
7726 else
7727 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307728 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
7729 __func__, hdd_device_modetoString(pAdapter->device_mode),
7730 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 return -EOPNOTSUPP;
7732 }
7733
7734
7735 if(pRoamProfile)
7736 {
7737 if ( LastBSSType != pRoamProfile->BSSType )
7738 {
7739 /*interface type changed update in wiphy structure*/
7740 wdev->iftype = type;
7741
7742 /*the BSS mode changed, We need to issue disconnect
7743 if connected or in IBSS disconnect state*/
7744 if ( hdd_connGetConnectedBssType(
7745 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
7746 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
7747 {
7748 /*need to issue a disconnect to CSR.*/
7749 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7750 if( eHAL_STATUS_SUCCESS ==
7751 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
7752 pAdapter->sessionId,
7753 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
7754 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307755 ret = wait_for_completion_interruptible_timeout(
7756 &pAdapter->disconnect_comp_var,
7757 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7758 if (ret <= 0)
7759 {
7760 hddLog(VOS_TRACE_LEVEL_ERROR,
7761 FL("wait on disconnect_comp_var failed %ld"), ret);
7762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 }
7764 }
7765 }
7766 }
7767
7768done:
7769 /*set bitmask based on updated value*/
7770 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07007771
7772 /* Only STA mode support TM now
7773 * all other mode, TM feature should be disabled */
7774 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
7775 (~VOS_STA & pHddCtx->concurrency_mode) )
7776 {
7777 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
7778 }
7779
Jeff Johnson295189b2012-06-20 16:38:30 -07007780#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307781 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05307782 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 {
7784 //we are ok to do AMP
7785 pHddCtx->isAmpAllowed = VOS_TRUE;
7786 }
7787#endif //WLAN_BTAMP_FEATURE
7788 EXIT();
7789 return 0;
7790}
7791
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05307792/*
7793 * FUNCTION: wlan_hdd_cfg80211_change_iface
7794 * wrapper function to protect the actual implementation from SSR.
7795 */
7796int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
7797 struct net_device *ndev,
7798 enum nl80211_iftype type,
7799 u32 *flags,
7800 struct vif_params *params
7801 )
7802{
7803 int ret;
7804
7805 vos_ssr_protect(__func__);
7806 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
7807 vos_ssr_unprotect(__func__);
7808
7809 return ret;
7810}
7811
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007812#ifdef FEATURE_WLAN_TDLS
7813static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
7814 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
7815{
7816 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7818 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007819 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307820 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307821 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007822
7823 ENTER();
7824
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307825 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007826 {
7827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7828 "Invalid arguments");
7829 return -EINVAL;
7830 }
Hoonki Lee27511902013-03-14 18:19:06 -07007831
7832 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
7833 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
7834 {
7835 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7836 "%s: TDLS mode is disabled OR not enabled in FW."
7837 MAC_ADDRESS_STR " Request declined.",
7838 __func__, MAC_ADDR_ARRAY(mac));
7839 return -ENOTSUPP;
7840 }
7841
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007842 if (pHddCtx->isLogpInProgress)
7843 {
7844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7845 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05307846 wlan_hdd_tdls_set_link_status(pAdapter,
7847 mac,
7848 eTDLS_LINK_IDLE,
7849 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007850 return -EBUSY;
7851 }
7852
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05307853 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007854
7855 if ( NULL == pTdlsPeer ) {
7856 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7857 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
7858 __func__, MAC_ADDR_ARRAY(mac), update);
7859 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007860 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007861
7862 /* in add station, we accept existing valid staId if there is */
7863 if ((0 == update) &&
7864 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
7865 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007866 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007867 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007868 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007869 " link_status %d. staId %d. add station ignored.",
7870 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
7871 return 0;
7872 }
7873 /* in change station, we accept only when staId is valid */
7874 if ((1 == update) &&
7875 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
7876 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
7877 {
7878 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7879 "%s: " MAC_ADDRESS_STR
7880 " link status %d. staId %d. change station %s.",
7881 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
7882 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
7883 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007884 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007885
7886 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307887 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007888 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7890 "%s: " MAC_ADDRESS_STR
7891 " TDLS setup is ongoing. Request declined.",
7892 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07007893 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007894 }
7895
7896 /* first to check if we reached to maximum supported TDLS peer.
7897 TODO: for now, return -EPERM looks working fine,
7898 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307899 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
7900 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007901 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7903 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307904 " TDLS Max peer already connected. Request declined."
7905 " Num of peers (%d), Max allowed (%d).",
7906 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
7907 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007908 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007909 }
7910 else
7911 {
7912 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307913 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007914 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007915 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7917 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
7918 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007919 return -EPERM;
7920 }
7921 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007922 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05307923 wlan_hdd_tdls_set_link_status(pAdapter,
7924 mac,
7925 eTDLS_LINK_CONNECTING,
7926 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007927
Jeff Johnsond75fe012013-04-06 10:53:06 -07007928 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307929 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007930 {
7931 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7932 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007933 if(StaParams->htcap_present)
7934 {
7935 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7936 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
7937 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7938 "ht_capa->extended_capabilities: %0x",
7939 StaParams->HTCap.extendedHtCapInfo);
7940 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007941 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7942 "params->capability: %0x",StaParams->capability);
7943 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007944 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07007945 if(StaParams->vhtcap_present)
7946 {
7947 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7948 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
7949 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
7950 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
7951 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007952 {
7953 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007955 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
7956 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7957 "[%d]: %x ", i, StaParams->supported_rates[i]);
7958 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07007959 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05307960 else if ((1 == update) && (NULL == StaParams))
7961 {
7962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7963 "%s : update is true, but staParams is NULL. Error!", __func__);
7964 return -EPERM;
7965 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007966
7967 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
7968
7969 if (!update)
7970 {
7971 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7972 pAdapter->sessionId, mac);
7973 }
7974 else
7975 {
7976 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
7977 pAdapter->sessionId, mac, StaParams);
7978 }
7979
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307980 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007981 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
7982
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307983 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007984 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307986 "%s: timeout waiting for tdls add station indication %ld",
7987 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007988 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007989 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307990
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007991 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
7992 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007994 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007995 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007996 }
7997
7998 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007999
8000error:
Atul Mittal115287b2014-07-08 13:26:33 +05308001 wlan_hdd_tdls_set_link_status(pAdapter,
8002 mac,
8003 eTDLS_LINK_IDLE,
8004 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008005 return -EPERM;
8006
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008007}
8008#endif
8009
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308010static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 struct net_device *dev,
8012 u8 *mac,
8013 struct station_parameters *params)
8014{
8015 VOS_STATUS status = VOS_STATUS_SUCCESS;
8016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05308017 hdd_context_t *pHddCtx;
8018 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308020 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008021#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008022 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008023 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308024 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008025#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008026 ENTER();
8027
Gopichand Nakkala29149562013-05-10 21:43:41 +05308028 if ((NULL == pAdapter))
8029 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308031 "invalid adapter ");
8032 return -EINVAL;
8033 }
8034
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308035 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8036 TRACE_CODE_HDD_CHANGE_STATION,
8037 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308039
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308040 ret = wlan_hdd_validate_context(pHddCtx);
8041 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308042 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8044 "%s: HDD context is not valid", __func__);
8045 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308046 }
8047
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308048 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8049
8050 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008051 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8053 "invalid HDD station context");
8054 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008055 }
8056
Jeff Johnson295189b2012-06-20 16:38:30 -07008057 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8058
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008059 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8060 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008062 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 WLANTL_STA_AUTHENTICATED);
8066
Gopichand Nakkala29149562013-05-10 21:43:41 +05308067 if (status != VOS_STATUS_SUCCESS)
8068 {
8069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8070 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8071 return -EINVAL;
8072 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 }
8074 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008075 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8076 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308077#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008078 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8079 StaParams.capability = params->capability;
8080 StaParams.uapsd_queues = params->uapsd_queues;
8081 StaParams.max_sp = params->max_sp;
8082
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308083 /* Convert (first channel , number of channels) tuple to
8084 * the total list of channels. This goes with the assumption
8085 * that if the first channel is < 14, then the next channels
8086 * are an incremental of 1 else an incremental of 4 till the number
8087 * of channels.
8088 */
8089 if (0 != params->supported_channels_len) {
8090 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8091 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8092 {
8093 int wifi_chan_index;
8094 StaParams.supported_channels[j] = params->supported_channels[i];
8095 wifi_chan_index =
8096 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8097 no_of_channels = params->supported_channels[i+1];
8098 for(k=1; k <= no_of_channels; k++)
8099 {
8100 StaParams.supported_channels[j+1] =
8101 StaParams.supported_channels[j] + wifi_chan_index;
8102 j+=1;
8103 }
8104 }
8105 StaParams.supported_channels_len = j;
8106 }
8107 vos_mem_copy(StaParams.supported_oper_classes,
8108 params->supported_oper_classes,
8109 params->supported_oper_classes_len);
8110 StaParams.supported_oper_classes_len =
8111 params->supported_oper_classes_len;
8112
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008113 if (0 != params->ext_capab_len)
8114 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8115 sizeof(StaParams.extn_capability));
8116
8117 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008118 {
8119 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008120 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008121 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008122
8123 StaParams.supported_rates_len = params->supported_rates_len;
8124
8125 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8126 * The supported_rates array , for all the structures propogating till Add Sta
8127 * to the firmware has to be modified , if the supplicant (ieee80211) is
8128 * modified to send more rates.
8129 */
8130
8131 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8132 */
8133 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8134 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8135
8136 if (0 != StaParams.supported_rates_len) {
8137 int i = 0;
8138 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8139 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008141 "Supported Rates with Length %d", StaParams.supported_rates_len);
8142 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008144 "[%d]: %0x", i, StaParams.supported_rates[i]);
8145 }
8146
8147 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008148 {
8149 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008150 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008151 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008152
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008153 if (0 != params->ext_capab_len ) {
8154 /*Define A Macro : TODO Sunil*/
8155 if ((1<<4) & StaParams.extn_capability[3]) {
8156 isBufSta = 1;
8157 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308158 /* TDLS Channel Switching Support */
8159 if ((1<<6) & StaParams.extn_capability[3]) {
8160 isOffChannelSupported = 1;
8161 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008162 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308163 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8164 &StaParams, isBufSta,
8165 isOffChannelSupported);
8166
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308167 if (VOS_STATUS_SUCCESS != status) {
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8169 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8170 return -EINVAL;
8171 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008172 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8173
8174 if (VOS_STATUS_SUCCESS != status) {
8175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8176 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8177 return -EINVAL;
8178 }
8179 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008180#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308181 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008182 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 return status;
8184}
8185
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308186static int wlan_hdd_change_station(struct wiphy *wiphy,
8187 struct net_device *dev,
8188 u8 *mac,
8189 struct station_parameters *params)
8190{
8191 int ret;
8192
8193 vos_ssr_protect(__func__);
8194 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8195 vos_ssr_unprotect(__func__);
8196
8197 return ret;
8198}
8199
Jeff Johnson295189b2012-06-20 16:38:30 -07008200/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308201 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 * This function is used to initialize the key information
8203 */
8204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308205static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 struct net_device *ndev,
8207 u8 key_index, bool pairwise,
8208 const u8 *mac_addr,
8209 struct key_params *params
8210 )
8211#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308212static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 struct net_device *ndev,
8214 u8 key_index, const u8 *mac_addr,
8215 struct key_params *params
8216 )
8217#endif
8218{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 tCsrRoamSetKey setKey;
8221 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308222 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008223 v_U32_t roamId= 0xFF;
8224 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 hdd_hostapd_state_t *pHostapdState;
8226 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008227 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308228 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
8230 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308231
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8233 TRACE_CODE_HDD_CFG80211_ADD_KEY,
8234 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8236 status = wlan_hdd_validate_context(pHddCtx);
8237
8238 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8241 "%s: HDD context is not valid", __func__);
8242 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008243 }
8244
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8246 __func__, hdd_device_modetoString(pAdapter->device_mode),
8247 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 if (CSR_MAX_NUM_KEY <= key_index)
8250 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 key_index);
8253
8254 return -EINVAL;
8255 }
8256
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008257 if (CSR_MAX_KEY_LEN < params->key_len)
8258 {
8259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
8260 params->key_len);
8261
8262 return -EINVAL;
8263 }
8264
8265 hddLog(VOS_TRACE_LEVEL_INFO,
8266 "%s: called with key index = %d & key length %d",
8267 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268
8269 /*extract key idx, key len and key*/
8270 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8271 setKey.keyId = key_index;
8272 setKey.keyLength = params->key_len;
8273 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
8274
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008275 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 {
8277 case WLAN_CIPHER_SUITE_WEP40:
8278 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
8279 break;
8280
8281 case WLAN_CIPHER_SUITE_WEP104:
8282 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
8283 break;
8284
8285 case WLAN_CIPHER_SUITE_TKIP:
8286 {
8287 u8 *pKey = &setKey.Key[0];
8288 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
8289
8290 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
8291
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008292 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07008293
8294 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008295 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 |--------------|----------|----------|
8297 <---16bytes---><--8bytes--><--8bytes-->
8298
8299 */
8300 /*Sme expects the 32 bytes key to be in the below order
8301
8302 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008303 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 |--------------|----------|----------|
8305 <---16bytes---><--8bytes--><--8bytes-->
8306 */
8307 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008308 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07008309
8310 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008311 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008312
8313 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008314 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07008315
8316
8317 break;
8318 }
8319
8320 case WLAN_CIPHER_SUITE_CCMP:
8321 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
8322 break;
8323
8324#ifdef FEATURE_WLAN_WAPI
8325 case WLAN_CIPHER_SUITE_SMS4:
8326 {
8327 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8328 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
8329 params->key, params->key_len);
8330 return 0;
8331 }
8332#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008333
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008334#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 case WLAN_CIPHER_SUITE_KRK:
8336 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
8337 break;
8338#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07008339
8340#ifdef WLAN_FEATURE_11W
8341 case WLAN_CIPHER_SUITE_AES_CMAC:
8342 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07008343 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07008344#endif
8345
Jeff Johnson295189b2012-06-20 16:38:30 -07008346 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07008348 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308349 status = -EOPNOTSUPP;
8350 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 }
8352
8353 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
8354 __func__, setKey.encType);
8355
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008356 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07008357#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8358 (!pairwise)
8359#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008360 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07008361#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008362 )
8363 {
8364 /* set group key*/
8365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8366 "%s- %d: setting Broadcast key",
8367 __func__, __LINE__);
8368 setKey.keyDirection = eSIR_RX_ONLY;
8369 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8370 }
8371 else
8372 {
8373 /* set pairwise key*/
8374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8375 "%s- %d: setting pairwise key",
8376 __func__, __LINE__);
8377 setKey.keyDirection = eSIR_TX_RX;
8378 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8379 }
8380 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
8381 {
8382 setKey.keyDirection = eSIR_TX_RX;
8383 /*Set the group key*/
8384 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8385 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07008386
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008387 if ( 0 != status )
8388 {
8389 hddLog(VOS_TRACE_LEVEL_ERROR,
8390 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308391 status = -EINVAL;
8392 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008393 }
8394 /*Save the keys here and call sme_RoamSetKey for setting
8395 the PTK after peer joins the IBSS network*/
8396 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
8397 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308398 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07008399 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05308400 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
8401 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
8402 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008404 if( pHostapdState->bssState == BSS_START )
8405 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 status = WLANSAP_SetKeySta( pVosContext, &setKey);
8407
8408 if ( status != eHAL_STATUS_SUCCESS )
8409 {
8410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8411 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8412 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308413 status = -EINVAL;
8414 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008415 }
8416 }
8417
8418 /* Saving WEP keys */
8419 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
8420 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
8421 {
8422 //Save the wep key in ap context. Issue setkey after the BSS is started.
8423 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
8424 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
8425 }
8426 else
8427 {
8428 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008429 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
8431 }
8432 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008433 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
8434 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 {
8436 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8437 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8438
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8440 if (!pairwise)
8441#else
8442 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8443#endif
8444 {
8445 /* set group key*/
8446 if (pHddStaCtx->roam_info.deferKeyComplete)
8447 {
8448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8449 "%s- %d: Perform Set key Complete",
8450 __func__, __LINE__);
8451 hdd_PerformRoamSetKeyComplete(pAdapter);
8452 }
8453 }
8454
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
8456
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08008457 pWextState->roamProfile.Keys.defaultIndex = key_index;
8458
8459
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07008460 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 params->key, params->key_len);
8462
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308463
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8465
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308468 __func__, setKey.peerMac[0], setKey.peerMac[1],
8469 setKey.peerMac[2], setKey.peerMac[3],
8470 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 setKey.keyDirection);
8472
Nirav Shah4f765af2015-01-21 19:51:30 +05308473 /* Wait for EAPOL M4 before setting key.
8474 * No need to consider Dynamic WEP as we will receive M8.
8475 */
8476 if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
8477 setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
8478 ( 1
8479#if defined WLAN_FEATURE_VOWIFI_11R
8480 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
8481 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
8482#endif
8483#ifdef FEATURE_WLAN_ESE
8484 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
8485 && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
8486#endif
8487 ))
Jeff Johnson295189b2012-06-20 16:38:30 -07008488 {
Nirav Shah4f765af2015-01-21 19:51:30 +05308489 vos_status = wlan_hdd_check_ula_done(pAdapter);
8490
8491 if ( vos_status != VOS_STATUS_SUCCESS )
8492 {
8493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
8495 __LINE__, vos_status );
8496
Nirav Shah4f765af2015-01-21 19:51:30 +05308497 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008498
Nirav Shah4f765af2015-01-21 19:51:30 +05308499 status = -EINVAL;
8500 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008501
Nirav Shah4f765af2015-01-21 19:51:30 +05308502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 }
8504
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008505#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308506 /* The supplicant may attempt to set the PTK once pre-authentication
8507 is done. Save the key in the UMAC and include it in the ADD BSS
8508 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008509 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308510 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008511 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308512 hddLog(VOS_TRACE_LEVEL_INFO_MED,
8513 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308514 status = 0;
8515 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05308516 }
8517 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
8518 {
8519 hddLog(VOS_TRACE_LEVEL_ERROR,
8520 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308521 status = -EINVAL;
8522 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008523 }
8524#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07008525
8526 /* issue set key request to SME*/
8527 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8528 pAdapter->sessionId, &setKey, &roamId );
8529
8530 if ( 0 != status )
8531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308532 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
8534 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308535 status = -EINVAL;
8536 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 }
8538
8539
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308540 /* in case of IBSS as there was no information available about WEP keys during
8541 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07008542 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308543 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
8544 !( ( IW_AUTH_KEY_MGMT_802_1X
8545 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
8547 )
8548 &&
8549 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
8550 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
8551 )
8552 )
8553 {
8554 setKey.keyDirection = eSIR_RX_ONLY;
8555 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
8556
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308557 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008558 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308559 __func__, setKey.peerMac[0], setKey.peerMac[1],
8560 setKey.peerMac[2], setKey.peerMac[3],
8561 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07008562 setKey.keyDirection);
8563
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308564 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 pAdapter->sessionId, &setKey, &roamId );
8566
8567 if ( 0 != status )
8568 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308569 hddLog(VOS_TRACE_LEVEL_ERROR,
8570 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 __func__, status);
8572 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308573 status = -EINVAL;
8574 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 }
8576 }
8577 }
8578
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308579end:
8580 /* Need to clear any trace of key value in the memory.
8581 * Thus zero out the memory even though it is local
8582 * variable.
8583 */
8584 vos_mem_zero(&setKey, sizeof(setKey));
8585
8586 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008587}
8588
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8590static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8591 struct net_device *ndev,
8592 u8 key_index, bool pairwise,
8593 const u8 *mac_addr,
8594 struct key_params *params
8595 )
8596#else
8597static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
8598 struct net_device *ndev,
8599 u8 key_index, const u8 *mac_addr,
8600 struct key_params *params
8601 )
8602#endif
8603{
8604 int ret;
8605 vos_ssr_protect(__func__);
8606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8607 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
8608 mac_addr, params);
8609#else
8610 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
8611 params);
8612#endif
8613 vos_ssr_unprotect(__func__);
8614
8615 return ret;
8616}
8617
Jeff Johnson295189b2012-06-20 16:38:30 -07008618/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308619 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008620 * This function is used to get the key information
8621 */
8622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308623static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308624 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308626 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 const u8 *mac_addr, void *cookie,
8628 void (*callback)(void *cookie, struct key_params*)
8629 )
8630#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308631static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308632 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 struct net_device *ndev,
8634 u8 key_index, const u8 *mac_addr, void *cookie,
8635 void (*callback)(void *cookie, struct key_params*)
8636 )
8637#endif
8638{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308640 hdd_wext_state_t *pWextState = NULL;
8641 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308643 hdd_context_t *pHddCtx;
8644 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008645
8646 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308647
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308648 if (NULL == pAdapter)
8649 {
8650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8651 "%s: HDD adapter is Null", __func__);
8652 return -ENODEV;
8653 }
8654
8655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8656 ret = wlan_hdd_validate_context(pHddCtx);
8657 if (0 != ret)
8658 {
8659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8660 "%s: HDD context is not valid", __func__);
8661 return ret;
8662 }
8663
8664 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8665 pRoamProfile = &(pWextState->roamProfile);
8666
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308667 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8668 __func__, hdd_device_modetoString(pAdapter->device_mode),
8669 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308670
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 memset(&params, 0, sizeof(params));
8672
8673 if (CSR_MAX_NUM_KEY <= key_index)
8674 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008678
8679 switch(pRoamProfile->EncryptionType.encryptionType[0])
8680 {
8681 case eCSR_ENCRYPT_TYPE_NONE:
8682 params.cipher = IW_AUTH_CIPHER_NONE;
8683 break;
8684
8685 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
8686 case eCSR_ENCRYPT_TYPE_WEP40:
8687 params.cipher = WLAN_CIPHER_SUITE_WEP40;
8688 break;
8689
8690 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
8691 case eCSR_ENCRYPT_TYPE_WEP104:
8692 params.cipher = WLAN_CIPHER_SUITE_WEP104;
8693 break;
8694
8695 case eCSR_ENCRYPT_TYPE_TKIP:
8696 params.cipher = WLAN_CIPHER_SUITE_TKIP;
8697 break;
8698
8699 case eCSR_ENCRYPT_TYPE_AES:
8700 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
8701 break;
8702
8703 default:
8704 params.cipher = IW_AUTH_CIPHER_NONE;
8705 break;
8706 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308707
c_hpothuaaf19692014-05-17 17:01:48 +05308708 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8709 TRACE_CODE_HDD_CFG80211_GET_KEY,
8710 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308711
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
8713 params.seq_len = 0;
8714 params.seq = NULL;
8715 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
8716 callback(cookie, &params);
8717 return 0;
8718}
8719
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8721static int wlan_hdd_cfg80211_get_key(
8722 struct wiphy *wiphy,
8723 struct net_device *ndev,
8724 u8 key_index, bool pairwise,
8725 const u8 *mac_addr, void *cookie,
8726 void (*callback)(void *cookie, struct key_params*)
8727 )
8728#else
8729static int wlan_hdd_cfg80211_get_key(
8730 struct wiphy *wiphy,
8731 struct net_device *ndev,
8732 u8 key_index, const u8 *mac_addr, void *cookie,
8733 void (*callback)(void *cookie, struct key_params*)
8734 )
8735#endif
8736{
8737 int ret;
8738
8739 vos_ssr_protect(__func__);
8740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8741 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
8742 mac_addr, cookie, callback);
8743#else
8744 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
8745 callback);
8746#endif
8747 vos_ssr_unprotect(__func__);
8748
8749 return ret;
8750}
8751
Jeff Johnson295189b2012-06-20 16:38:30 -07008752/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308753 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008754 * This function is used to delete the key information
8755 */
8756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308757static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308759 u8 key_index,
8760 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 const u8 *mac_addr
8762 )
8763#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308764static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 struct net_device *ndev,
8766 u8 key_index,
8767 const u8 *mac_addr
8768 )
8769#endif
8770{
8771 int status = 0;
8772
8773 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308774 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 //it is observed that this is invalidating peer
8776 //key index whenever re-key is done. This is affecting data link.
8777 //It should be ok to ignore del_key.
8778#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
8780 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
8782 tCsrRoamSetKey setKey;
8783 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308784
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 ENTER();
8786
8787 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
8788 __func__,pAdapter->device_mode);
8789
8790 if (CSR_MAX_NUM_KEY <= key_index)
8791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 key_index);
8794
8795 return -EINVAL;
8796 }
8797
8798 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8799 setKey.keyId = key_index;
8800
8801 if (mac_addr)
8802 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
8803 else
8804 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
8805
8806 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
8807
8808 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308810 )
8811 {
8812
8813 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8815 if( pHostapdState->bssState == BSS_START)
8816 {
8817 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308818
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 if ( status != eHAL_STATUS_SUCCESS )
8820 {
8821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8822 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
8823 __LINE__, status );
8824 }
8825 }
8826 }
8827 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308828 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 )
8830 {
8831 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8832
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308833 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8834
8835 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308837 __func__, setKey.peerMac[0], setKey.peerMac[1],
8838 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308840 if(pAdapter->sessionCtx.station.conn_info.connState ==
8841 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308843 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308845
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 if ( 0 != status )
8847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308848 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 "%s: sme_RoamSetKey failure, returned %d",
8850 __func__, status);
8851 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8852 return -EINVAL;
8853 }
8854 }
8855 }
8856#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008857 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 return status;
8859}
8860
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308861#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8862static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8863 struct net_device *ndev,
8864 u8 key_index,
8865 bool pairwise,
8866 const u8 *mac_addr
8867 )
8868#else
8869static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
8870 struct net_device *ndev,
8871 u8 key_index,
8872 const u8 *mac_addr
8873 )
8874#endif
8875{
8876 int ret;
8877
8878 vos_ssr_protect(__func__);
8879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8880 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
8881 mac_addr);
8882#else
8883 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
8884#endif
8885 vos_ssr_unprotect(__func__);
8886
8887 return ret;
8888}
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308891 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 * This function is used to set the default tx key index
8893 */
8894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308895static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 struct net_device *ndev,
8897 u8 key_index,
8898 bool unicast, bool multicast)
8899#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05308900static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 struct net_device *ndev,
8902 u8 key_index)
8903#endif
8904{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308906 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308907 hdd_wext_state_t *pWextState;
8908 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308909 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910
8911 ENTER();
8912
Gopichand Nakkala29149562013-05-10 21:43:41 +05308913 if ((NULL == pAdapter))
8914 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308916 "invalid adapter");
8917 return -EINVAL;
8918 }
8919
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308920 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8921 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
8922 pAdapter->sessionId, key_index));
8923
Gopichand Nakkala29149562013-05-10 21:43:41 +05308924 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8925 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8926
8927 if ((NULL == pWextState) || (NULL == pHddStaCtx))
8928 {
8929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8930 "invalid Wext state or HDD context");
8931 return -EINVAL;
8932 }
8933
Arif Hussain6d2a3322013-11-17 19:50:10 -08008934 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308936
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 if (CSR_MAX_NUM_KEY <= key_index)
8938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 key_index);
8941
8942 return -EINVAL;
8943 }
8944
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308945 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8946 status = wlan_hdd_validate_context(pHddCtx);
8947
8948 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8951 "%s: HDD context is not valid", __func__);
8952 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008953 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308954
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308957 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308959 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08008960 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308961 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08008962 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308964 {
8965 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308967
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 tCsrRoamSetKey setKey;
8969 v_U32_t roamId= 0xFF;
8970 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308971
8972 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308974
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 Keys->defaultIndex = (u8)key_index;
8976 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
8977 setKey.keyId = key_index;
8978 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308979
8980 vos_mem_copy(&setKey.Key[0],
8981 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308983
Gopichand Nakkala29149562013-05-10 21:43:41 +05308984 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985
8986 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 &pHddStaCtx->conn_info.bssId[0],
8988 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308989
Gopichand Nakkala29149562013-05-10 21:43:41 +05308990 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
8991 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
8992 eCSR_ENCRYPT_TYPE_WEP104)
8993 {
8994 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
8995 even though ap is configured for WEP-40 encryption. In this canse the key length
8996 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
8997 type(104) and switching encryption type to 40*/
8998 pWextState->roamProfile.EncryptionType.encryptionType[0] =
8999 eCSR_ENCRYPT_TYPE_WEP40;
9000 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9001 eCSR_ENCRYPT_TYPE_WEP40;
9002 }
9003
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309004 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309006
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309008 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309010
Jeff Johnson295189b2012-06-20 16:38:30 -07009011 if ( 0 != status )
9012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309013 hddLog(VOS_TRACE_LEVEL_ERROR,
9014 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 status);
9016 return -EINVAL;
9017 }
9018 }
9019 }
9020
9021 /* In SoftAp mode setting key direction for default mode */
9022 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9023 {
9024 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9025 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9026 (eCSR_ENCRYPT_TYPE_AES !=
9027 pWextState->roamProfile.EncryptionType.encryptionType[0])
9028 )
9029 {
9030 /* Saving key direction for default key index to TX default */
9031 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9032 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9033 }
9034 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309035
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 return status;
9037}
9038
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9040static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9041 struct net_device *ndev,
9042 u8 key_index,
9043 bool unicast, bool multicast)
9044#else
9045static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9046 struct net_device *ndev,
9047 u8 key_index)
9048#endif
9049{
9050 int ret;
9051 vos_ssr_protect(__func__);
9052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9053 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9054 multicast);
9055#else
9056 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9057#endif
9058 vos_ssr_unprotect(__func__);
9059
9060 return ret;
9061}
9062
Jeff Johnson295189b2012-06-20 16:38:30 -07009063/*
9064 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9065 * This function is used to inform the BSS details to nl80211 interface.
9066 */
9067static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9068 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9069{
9070 struct net_device *dev = pAdapter->dev;
9071 struct wireless_dev *wdev = dev->ieee80211_ptr;
9072 struct wiphy *wiphy = wdev->wiphy;
9073 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9074 int chan_no;
9075 int ie_length;
9076 const char *ie;
9077 unsigned int freq;
9078 struct ieee80211_channel *chan;
9079 int rssi = 0;
9080 struct cfg80211_bss *bss = NULL;
9081
9082 ENTER();
9083
9084 if( NULL == pBssDesc )
9085 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009086 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009087 return bss;
9088 }
9089
9090 chan_no = pBssDesc->channelId;
9091 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9092 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9093
9094 if( NULL == ie )
9095 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 return bss;
9098 }
9099
9100#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9101 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9102 {
9103 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9104 }
9105 else
9106 {
9107 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9108 }
9109#else
9110 freq = ieee80211_channel_to_frequency(chan_no);
9111#endif
9112
9113 chan = __ieee80211_get_channel(wiphy, freq);
9114
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309115 if (!chan) {
9116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9117 return NULL;
9118 }
9119
Abhishek Singhaee43942014-06-16 18:55:47 +05309120 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009121
Abhishek Singhaee43942014-06-16 18:55:47 +05309122 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309123 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 pBssDesc->capabilityInfo,
9125 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309126 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009127}
9128
9129
9130
9131/*
9132 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9133 * This function is used to inform the BSS details to nl80211 interface.
9134 */
9135struct cfg80211_bss*
9136wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9137 tSirBssDescription *bss_desc
9138 )
9139{
9140 /*
9141 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9142 already exists in bss data base of cfg80211 for that particular BSS ID.
9143 Using cfg80211_inform_bss_frame to update the bss entry instead of
9144 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9145 now there is no possibility to get the mgmt(probe response) frame from PE,
9146 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9147 cfg80211_inform_bss_frame.
9148 */
9149 struct net_device *dev = pAdapter->dev;
9150 struct wireless_dev *wdev = dev->ieee80211_ptr;
9151 struct wiphy *wiphy = wdev->wiphy;
9152 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009153#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9154 qcom_ie_age *qie_age = NULL;
9155 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9156#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 const char *ie =
9160 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9161 unsigned int freq;
9162 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309163 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 struct cfg80211_bss *bss_status = NULL;
9165 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9166 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009167 hdd_context_t *pHddCtx;
9168 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009169#ifdef WLAN_OPEN_SOURCE
9170 struct timespec ts;
9171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009172
Wilson Yangf80a0542013-10-07 13:02:37 -07009173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9174 status = wlan_hdd_validate_context(pHddCtx);
9175
9176 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309177 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009178 {
9179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9180 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9181 return NULL;
9182 }
9183
9184
9185 if (0 != status)
9186 {
9187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9188 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009189 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009190 }
9191
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309192 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009193 if (!mgmt)
9194 {
9195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9196 "%s: memory allocation failed ", __func__);
9197 return NULL;
9198 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009199
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009201
9202#ifdef WLAN_OPEN_SOURCE
9203 /* Android does not want the timestamp from the frame.
9204 Instead it wants a monotonic increasing value */
9205 get_monotonic_boottime(&ts);
9206 mgmt->u.probe_resp.timestamp =
9207 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9208#else
9209 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9211 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009212
9213#endif
9214
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9216 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009217
9218#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9219 /* GPS Requirement: need age ie per entry. Using vendor specific. */
9220 /* Assuming this is the last IE, copy at the end */
9221 ie_length -=sizeof(qcom_ie_age);
9222 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
9223 qie_age->element_id = QCOM_VENDOR_IE_ID;
9224 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
9225 qie_age->oui_1 = QCOM_OUI1;
9226 qie_age->oui_2 = QCOM_OUI2;
9227 qie_age->oui_3 = QCOM_OUI3;
9228 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
9229 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
9230#endif
9231
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05309233 if (bss_desc->fProbeRsp)
9234 {
9235 mgmt->frame_control |=
9236 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
9237 }
9238 else
9239 {
9240 mgmt->frame_control |=
9241 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
9242 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009243
9244#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309245 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
9247 {
9248 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9249 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309250 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
9252
9253 {
9254 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9255 }
9256 else
9257 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
9259 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 kfree(mgmt);
9261 return NULL;
9262 }
9263#else
9264 freq = ieee80211_channel_to_frequency(chan_no);
9265#endif
9266 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009267 /*when the band is changed on the fly using the GUI, three things are done
9268 * 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)
9269 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
9270 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
9271 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
9272 * and discards the channels correponding to previous band and calls back with zero bss results.
9273 * 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
9274 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
9275 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
9276 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
9277 * So drop the bss and continue to next bss.
9278 */
9279 if(chan == NULL)
9280 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07009282 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08009283 return NULL;
9284 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309286 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 * */
9288 if (( eConnectionState_Associated ==
9289 pAdapter->sessionCtx.station.conn_info.connState ) &&
9290 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
9291 pAdapter->sessionCtx.station.conn_info.bssId,
9292 WNI_CFG_BSSID_LEN)))
9293 {
9294 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
9295 rssi = (pAdapter->rssi * 100);
9296 }
9297 else
9298 {
9299 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
9300 }
9301
Nirav Shah20ac06f2013-12-12 18:14:06 +05309302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
9303 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
9304 chan->center_freq, (int)(rssi/100));
9305
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
9307 frame_len, rssi, GFP_KERNEL);
9308 kfree(mgmt);
9309 return bss_status;
9310}
9311
9312/*
9313 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
9314 * This function is used to update the BSS data base of CFG8011
9315 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 tCsrRoamInfo *pRoamInfo
9318 )
9319{
9320 tCsrRoamConnectedProfile roamProfile;
9321 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9322 struct cfg80211_bss *bss = NULL;
9323
9324 ENTER();
9325
9326 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
9327 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
9328
9329 if (NULL != roamProfile.pBssDesc)
9330 {
Girish Gowlif4b68022014-08-28 23:18:57 +05309331 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9332 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009333
9334 if (NULL == bss)
9335 {
9336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
9337 __func__);
9338 }
9339
9340 sme_RoamFreeConnectProfile(hHal, &roamProfile);
9341 }
9342 else
9343 {
9344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
9345 __func__);
9346 }
9347 return bss;
9348}
9349
9350/*
9351 * FUNCTION: wlan_hdd_cfg80211_update_bss
9352 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309353static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
9354 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309356{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309357 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 tCsrScanResultInfo *pScanResult;
9359 eHalStatus status = 0;
9360 tScanResultHandle pResult;
9361 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009362 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009363
9364 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9367 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
9368 NO_SESSION, pAdapter->sessionId));
9369
Wilson Yangf80a0542013-10-07 13:02:37 -07009370 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9371
9372 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 {
Wilson Yangf80a0542013-10-07 13:02:37 -07009374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9375 "%s:LOGP in Progress. Ignore!!!",__func__);
9376 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 }
9378
Wilson Yangf80a0542013-10-07 13:02:37 -07009379
9380 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05309381 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07009382 {
9383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9384 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
9385 return VOS_STATUS_E_PERM;
9386 }
9387
9388
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 /*
9390 * start getting scan results and populate cgf80211 BSS database
9391 */
9392 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
9393
9394 /* no scan results */
9395 if (NULL == pResult)
9396 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
9398 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 return status;
9400 }
9401
9402 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
9403
9404 while (pScanResult)
9405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309406 /*
9407 * cfg80211_inform_bss() is not updating ie field of bss entry, if
9408 * entry already exists in bss data base of cfg80211 for that
9409 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
9410 * bss entry instead of cfg80211_inform_bss, But this call expects
9411 * mgmt packet as input. As of now there is no possibility to get
9412 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 * ieee80211_mgmt(probe response) and passing to c
9414 * fg80211_inform_bss_frame.
9415 * */
9416
9417 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
9418 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
9421 if (NULL == bss_status)
9422 {
9423 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009424 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 }
9426 else
9427 {
Yue Maf49ba872013-08-19 12:04:25 -07009428 cfg80211_put_bss(
9429#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
9430 wiphy,
9431#endif
9432 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 }
9434
9435 pScanResult = sme_ScanResultGetNext(hHal, pResult);
9436 }
9437
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309438 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07009439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309440 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009441}
9442
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009443void
9444hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
9445{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309446 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08009447 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009448} /****** end hddPrintMacAddr() ******/
9449
9450void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009451hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009452{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309453 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009454 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07009455 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
9456 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
9457 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009458} /****** end hddPrintPmkId() ******/
9459
9460//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
9461//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
9462
9463//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
9464//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
9465
9466#define dump_bssid(bssid) \
9467 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009468 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
9469 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009470 }
9471
9472#define dump_pmkid(pMac, pmkid) \
9473 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07009474 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
9475 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009476 }
9477
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009478#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009479/*
9480 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
9481 * This function is used to notify the supplicant of a new PMKSA candidate.
9482 */
9483int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309484 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009485 int index, bool preauth )
9486{
Jeff Johnsone7245742012-09-05 17:12:55 -07009487#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009488 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009489 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009490
9491 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07009492 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009493
9494 if( NULL == pRoamInfo )
9495 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009496 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009497 return -EINVAL;
9498 }
9499
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009500 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
9501 {
9502 dump_bssid(pRoamInfo->bssid);
9503 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009504 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07009505 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009506#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309507 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009508}
9509#endif //FEATURE_WLAN_LFR
9510
Yue Maef608272013-04-08 23:09:17 -07009511#ifdef FEATURE_WLAN_LFR_METRICS
9512/*
9513 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
9514 * 802.11r/LFR metrics reporting function to report preauth initiation
9515 *
9516 */
9517#define MAX_LFR_METRICS_EVENT_LENGTH 100
9518VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
9519 tCsrRoamInfo *pRoamInfo)
9520{
9521 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9522 union iwreq_data wrqu;
9523
9524 ENTER();
9525
9526 if (NULL == pAdapter)
9527 {
9528 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9529 return VOS_STATUS_E_FAILURE;
9530 }
9531
9532 /* create the event */
9533 memset(&wrqu, 0, sizeof(wrqu));
9534 memset(metrics_notification, 0, sizeof(metrics_notification));
9535
9536 wrqu.data.pointer = metrics_notification;
9537 wrqu.data.length = scnprintf(metrics_notification,
9538 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
9539 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9540
9541 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9542
9543 EXIT();
9544
9545 return VOS_STATUS_SUCCESS;
9546}
9547
9548/*
9549 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
9550 * 802.11r/LFR metrics reporting function to report preauth completion
9551 * or failure
9552 */
9553VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
9554 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
9555{
9556 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9557 union iwreq_data wrqu;
9558
9559 ENTER();
9560
9561 if (NULL == pAdapter)
9562 {
9563 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9564 return VOS_STATUS_E_FAILURE;
9565 }
9566
9567 /* create the event */
9568 memset(&wrqu, 0, sizeof(wrqu));
9569 memset(metrics_notification, 0, sizeof(metrics_notification));
9570
9571 scnprintf(metrics_notification, sizeof(metrics_notification),
9572 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
9573 MAC_ADDR_ARRAY(pRoamInfo->bssid));
9574
9575 if (1 == preauth_status)
9576 strncat(metrics_notification, " TRUE", 5);
9577 else
9578 strncat(metrics_notification, " FALSE", 6);
9579
9580 wrqu.data.pointer = metrics_notification;
9581 wrqu.data.length = strlen(metrics_notification);
9582
9583 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9584
9585 EXIT();
9586
9587 return VOS_STATUS_SUCCESS;
9588}
9589
9590/*
9591 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
9592 * 802.11r/LFR metrics reporting function to report handover initiation
9593 *
9594 */
9595VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
9596 tCsrRoamInfo *pRoamInfo)
9597{
9598 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
9599 union iwreq_data wrqu;
9600
9601 ENTER();
9602
9603 if (NULL == pAdapter)
9604 {
9605 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
9606 return VOS_STATUS_E_FAILURE;
9607 }
9608
9609 /* create the event */
9610 memset(&wrqu, 0, sizeof(wrqu));
9611 memset(metrics_notification, 0, sizeof(metrics_notification));
9612
9613 wrqu.data.pointer = metrics_notification;
9614 wrqu.data.length = scnprintf(metrics_notification,
9615 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
9616 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
9617
9618 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
9619
9620 EXIT();
9621
9622 return VOS_STATUS_SUCCESS;
9623}
9624#endif
9625
Jeff Johnson295189b2012-06-20 16:38:30 -07009626/*
9627 * FUNCTION: hdd_cfg80211_scan_done_callback
9628 * scanning callback function, called after finishing scan
9629 *
9630 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309631static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
9633{
9634 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309635 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009637 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9638 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 struct cfg80211_scan_request *req = NULL;
9640 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309641 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309642 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309643 tANI_U8 i;
Jeff Johnson295189b2012-06-20 16:38:30 -07009644
9645 ENTER();
9646
9647 hddLog(VOS_TRACE_LEVEL_INFO,
9648 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08009649 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 __func__, halHandle, pContext, (int) scanId, (int) status);
9651
Kiet Lamac06e2c2013-10-23 16:25:07 +05309652 pScanInfo->mScanPendingCounter = 0;
9653
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309655 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 &pScanInfo->scan_req_completion_event,
9657 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309658 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309660 hddLog(VOS_TRACE_LEVEL_ERROR,
9661 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009663 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 }
9665
Yue Maef608272013-04-08 23:09:17 -07009666 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 {
9668 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009669 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 }
9671
9672 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309673 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 {
9675 hddLog(VOS_TRACE_LEVEL_INFO,
9676 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009677 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 (int) scanId);
9679 }
9680
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309681 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009682 pAdapter);
9683
9684 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009686
9687
9688 /* If any client wait scan result through WEXT
9689 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009690 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 {
9692 /* The other scan request waiting for current scan finish
9693 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009694 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009696 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 }
9698 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009699 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 {
9701 struct net_device *dev = pAdapter->dev;
9702 union iwreq_data wrqu;
9703 int we_event;
9704 char *msg;
9705
9706 memset(&wrqu, '\0', sizeof(wrqu));
9707 we_event = SIOCGIWSCAN;
9708 msg = NULL;
9709 wireless_send_event(dev, we_event, &wrqu, msg);
9710 }
9711 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009712 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009713
9714 /* Get the Scan Req */
9715 req = pAdapter->request;
9716
9717 if (!req)
9718 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009719 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009720 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009721 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 }
9723
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009725 /* Scan is no longer pending */
9726 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009727
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309728 /* last_scan_timestamp is used to decide if new scan
9729 * is needed or not on station interface. If last station
9730 * scan time and new station scan time is less then
9731 * last_scan_timestamp ; driver will return cached scan.
9732 */
9733 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
9734 {
9735 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
9736
9737 if ( req->n_channels )
9738 {
9739 for (i = 0; i < req->n_channels ; i++ )
9740 {
9741 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
9742 }
9743 /* store no of channel scanned */
9744 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
9745 }
9746
9747 }
9748
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07009749 /*
9750 * cfg80211_scan_done informing NL80211 about completion
9751 * of scanning
9752 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05309753 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
9754 {
9755 aborted = true;
9756 }
9757 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009758 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009759
Siddharth Bhal76972212014-10-15 16:22:51 +05309760 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
9761 /* Generate new random mac addr for next scan */
9762 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
9763 hdd_processSpoofMacAddrRequest(pHddCtx);
9764 }
9765
Jeff Johnsone7245742012-09-05 17:12:55 -07009766allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009767 /* release the wake lock at the end of the scan*/
9768 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009769
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009770 /* Acquire wakelock to handle the case where APP's tries to suspend
9771 * immediatly after the driver gets connect request(i.e after scan)
9772 * from supplicant, this result in app's is suspending and not able
9773 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309774 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009775
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009776#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05309777 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
9778 {
9779 wlan_hdd_tdls_scan_done_callback(pAdapter);
9780 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009781#endif
9782
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 EXIT();
9784 return 0;
9785}
9786
9787/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05309788 * FUNCTION: hdd_isConnectionInProgress
9789 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009790 *
9791 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309792v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009793{
9794 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9795 hdd_station_ctx_t *pHddStaCtx = NULL;
9796 hdd_adapter_t *pAdapter = NULL;
9797 VOS_STATUS status = 0;
9798 v_U8_t staId = 0;
9799 v_U8_t *staMac = NULL;
9800
c_hpothu9b781ba2013-12-30 20:57:45 +05309801 if (TRUE == pHddCtx->btCoexModeSet)
9802 {
9803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05309804 FL("BTCoex Mode operation in progress"));
9805 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05309806 }
9807
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009808 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9809
9810 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9811 {
9812 pAdapter = pAdapterNode->pAdapter;
9813
9814 if( pAdapter )
9815 {
9816 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309817 "%s: Adapter with device mode %s (%d) exists",
9818 __func__, hdd_device_modetoString(pAdapter->device_mode),
9819 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309820 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +05309821 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9822 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
9823 (eConnectionState_Connecting ==
9824 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
9825 {
9826 hddLog(VOS_TRACE_LEVEL_ERROR,
9827 "%s: %p(%d) Connection is in progress", __func__,
9828 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9829 return VOS_TRUE;
9830 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309831 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +05309832 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +05309833 {
9834 hddLog(VOS_TRACE_LEVEL_ERROR,
9835 "%s: %p(%d) Reassociation is in progress", __func__,
9836 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
9837 return VOS_TRUE;
9838 }
9839 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309840 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
9841 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009842 {
9843 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9844 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309845 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009846 {
9847 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
9848 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009849 "%s: client " MAC_ADDRESS_STR
9850 " is in the middle of WPS/EAPOL exchange.", __func__,
9851 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309852 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009853 }
9854 }
9855 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
9856 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
9857 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309858 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9859 ptSapContext pSapCtx = NULL;
9860 pSapCtx = VOS_GET_SAP_CB(pVosContext);
9861 if(pSapCtx == NULL){
9862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9863 FL("psapCtx is NULL"));
9864 return VOS_FALSE;
9865 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009866 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
9867 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309868 if ((pSapCtx->aStaInfo[staId].isUsed) &&
9869 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009870 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +05309871 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009872
9873 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08009874 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
9875 "middle of WPS/EAPOL exchange.", __func__,
9876 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05309877 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009878 }
9879 }
9880 }
9881 }
9882 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9883 pAdapterNode = pNext;
9884 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05309885 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309886}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08009887
9888/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309889 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 * this scan respond to scan trigger and update cfg80211 scan database
9891 * later, scan dump command can be used to recieve scan results
9892 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309893int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009894#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9895 struct net_device *dev,
9896#endif
9897 struct cfg80211_scan_request *request)
9898{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309899 hdd_adapter_t *pAdapter = NULL;
9900 hdd_context_t *pHddCtx = NULL;
9901 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309902 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 tCsrScanRequest scanRequest;
9904 tANI_U8 *channelList = NULL, i;
9905 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309906 int status;
9907 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +05309909 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009910
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
9912 struct net_device *dev = NULL;
9913 if (NULL == request)
9914 {
9915 hddLog(VOS_TRACE_LEVEL_ERROR,
9916 "%s: scan req param null", __func__);
9917 return -EINVAL;
9918 }
9919 dev = request->wdev->netdev;
9920#endif
9921
9922 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
9923 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9924 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9925
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 ENTER();
9927
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309928
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9930 __func__, hdd_device_modetoString(pAdapter->device_mode),
9931 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309932
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309933 status = wlan_hdd_validate_context(pHddCtx);
9934
9935 if (0 != status)
9936 {
9937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9938 "%s: HDD context is not valid", __func__);
9939 return status;
9940 }
9941
Siddharth Bhal0c162d02014-05-06 19:50:42 +05309942 if (NULL == pwextBuf)
9943 {
9944 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
9945 __func__);
9946 return -EIO;
9947 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309948 cfg_param = pHddCtx->cfg_ini;
9949 pScanInfo = &pHddCtx->scan_info;
9950
Jeff Johnson295189b2012-06-20 16:38:30 -07009951#ifdef WLAN_BTAMP_FEATURE
9952 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009953 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009955 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 "%s: No scanning when AMP is on", __func__);
9957 return -EOPNOTSUPP;
9958 }
9959#endif
9960 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009961 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009963 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309964 "%s: Not scanning on device_mode = %s (%d)",
9965 __func__, hdd_device_modetoString(pAdapter->device_mode),
9966 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 return -EOPNOTSUPP;
9968 }
9969
9970 if (TRUE == pScanInfo->mScanPending)
9971 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309972 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
9973 {
9974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
9975 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009976 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309979 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07009980 //Channel and action frame is pending
9981 //Otherwise Cancel Remain On Channel and allow Scan
9982 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009983 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07009984 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05309985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009986 return -EBUSY;
9987 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009988#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009989 /* if tdls disagree scan right now, return immediately.
9990 tdls will schedule the scan when scan is allowed. (return SUCCESS)
9991 or will reject the scan if any TDLS is in progress. (return -EBUSY)
9992 */
9993 status = wlan_hdd_tdls_scan_callback (pAdapter,
9994 wiphy,
9995#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9996 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07009997#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07009998 request);
9999 if(status <= 0)
10000 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010001 if(!status)
10002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
10003 "scan rejected %d", __func__, status);
10004 else
10005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
10006 __func__, status);
10007
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010008 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010009 }
10010#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070010011
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10013 {
10014 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010015 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010017 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10019 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010020 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 "%s: MAX TM Level Scan not allowed", __func__);
10022 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 }
10025 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10026
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010027 /* Check if scan is allowed at this point of time.
10028 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010029 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010030 {
10031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10032 return -EBUSY;
10033 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10036
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010037 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
10038 (int)request->n_ssids);
10039
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010040
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010041 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10042 * Becasue of this, driver is assuming that this is not wildcard scan and so
10043 * is not aging out the scan results.
10044 */
10045 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010047 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010049
10050 if ((request->ssids) && (0 < request->n_ssids))
10051 {
10052 tCsrSSIDInfo *SsidInfo;
10053 int j;
10054 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10055 /* Allocate num_ssid tCsrSSIDInfo structure */
10056 SsidInfo = scanRequest.SSIDs.SSIDList =
10057 ( tCsrSSIDInfo *)vos_mem_malloc(
10058 request->n_ssids*sizeof(tCsrSSIDInfo));
10059
10060 if(NULL == scanRequest.SSIDs.SSIDList)
10061 {
10062 hddLog(VOS_TRACE_LEVEL_ERROR,
10063 "%s: memory alloc failed SSIDInfo buffer", __func__);
10064 return -ENOMEM;
10065 }
10066
10067 /* copy all the ssid's and their length */
10068 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10069 {
10070 /* get the ssid length */
10071 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10072 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10073 SsidInfo->SSID.length);
10074 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10075 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10076 j, SsidInfo->SSID.ssId);
10077 }
10078 /* set the scan type to active */
10079 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10080 }
10081 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10084 TRACE_CODE_HDD_CFG80211_SCAN,
10085 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010086 /* set the scan type to active */
10087 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010089 else
10090 {
10091 /*Set the scan type to default type, in this case it is ACTIVE*/
10092 scanRequest.scanType = pScanInfo->scan_mode;
10093 }
10094 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10095 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010096
10097 /* set BSSType to default type */
10098 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10099
10100 /*TODO: scan the requested channels only*/
10101
10102 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010103 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010105 hddLog(VOS_TRACE_LEVEL_WARN,
10106 "No of Scan Channels exceeded limit: %d", request->n_channels);
10107 request->n_channels = MAX_CHANNEL;
10108 }
10109
10110 hddLog(VOS_TRACE_LEVEL_INFO,
10111 "No of Scan Channels: %d", request->n_channels);
10112
10113
10114 if( request->n_channels )
10115 {
10116 char chList [(request->n_channels*5)+1];
10117 int len;
10118 channelList = vos_mem_malloc( request->n_channels );
10119 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010120 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010121 hddLog(VOS_TRACE_LEVEL_ERROR,
10122 "%s: memory alloc failed channelList", __func__);
10123 status = -ENOMEM;
10124 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010125 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010126
10127 for( i = 0, len = 0; i < request->n_channels ; i++ )
10128 {
10129 channelList[i] = request->channels[i]->hw_value;
10130 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10131 }
10132
Nirav Shah20ac06f2013-12-12 18:14:06 +053010133 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010134 "Channel-List: %s ", chList);
10135 }
c_hpothu53512302014-04-15 18:49:53 +053010136
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010137 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10138 scanRequest.ChannelInfo.ChannelList = channelList;
10139
10140 /* set requestType to full scan */
10141 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10142
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010143 /* if there is back to back scan happening in driver with in
10144 * nDeferScanTimeInterval interval driver should defer new scan request
10145 * and should provide last cached scan results instead of new channel list.
10146 * This rule is not applicable if scan is p2p scan.
10147 * This condition will work only in case when last request no of channels
10148 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010149 * This should be done only in connected state
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010150 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010151
Agarwal Ashish57e84372014-12-05 18:26:53 +053010152 if ((VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
10153 {
10154 if ( pScanInfo->last_scan_timestamp !=0 &&
10155 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10156 {
10157 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10158 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10159 vos_mem_compare(pScanInfo->last_scan_channelList,
10160 channelList, pScanInfo->last_scan_numChannels))
10161 {
10162 hddLog(VOS_TRACE_LEVEL_WARN,
10163 " New and old station scan time differ is less then %u",
10164 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10165
10166 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010167 pAdapter);
10168
Agarwal Ashish57e84372014-12-05 18:26:53 +053010169 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010170 "Return old cached scan as all channels and no of channels are same");
10171
Agarwal Ashish57e84372014-12-05 18:26:53 +053010172 if (0 > ret)
10173 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010174
Agarwal Ashish57e84372014-12-05 18:26:53 +053010175 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010176
10177 status = eHAL_STATUS_SUCCESS;
10178 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010179 }
10180 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010181 }
10182
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010183 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10184 * search (Flush on both full scan and social scan but not on single
10185 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10186 */
10187
10188 /* Supplicant does single channel scan after 8-way handshake
10189 * and in that case driver shoudnt flush scan results. If
10190 * driver flushes the scan results here and unfortunately if
10191 * the AP doesnt respond to our probe req then association
10192 * fails which is not desired
10193 */
10194
10195 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10196 {
10197 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10198 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10199 pAdapter->sessionId );
10200 }
10201
10202 if( request->ie_len )
10203 {
10204 /* save this for future association (join requires this) */
10205 /*TODO: Array needs to be converted to dynamic allocation,
10206 * as multiple ie.s can be sent in cfg80211_scan_request structure
10207 * CR 597966
10208 */
10209 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10210 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10211 pScanInfo->scanAddIE.length = request->ie_len;
10212
10213 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10214 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10215 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010217 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010219 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10220 memcpy( pwextBuf->roamProfile.addIEScan,
10221 request->ie, request->ie_len);
10222 }
10223 else
10224 {
10225 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10226 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010227 }
10228
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010229 }
10230 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10231 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10232
10233 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10234 request->ie_len);
10235 if (pP2pIe != NULL)
10236 {
10237#ifdef WLAN_FEATURE_P2P_DEBUG
10238 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10239 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10240 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010241 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010242 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10243 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10244 "Go nego completed to Connection is started");
10245 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10246 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010247 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010248 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10249 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010251 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10252 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10253 "Disconnected state to Connection is started");
10254 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10255 "for 4way Handshake");
10256 }
10257#endif
10258
10259 /* no_cck will be set during p2p find to disable 11b rates */
10260 if(TRUE == request->no_cck)
10261 {
10262 hddLog(VOS_TRACE_LEVEL_INFO,
10263 "%s: This is a P2P Search", __func__);
10264 scanRequest.p2pSearch = 1;
10265
10266 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010267 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010268 /* set requestType to P2P Discovery */
10269 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10270 }
10271
10272 /*
10273 Skip Dfs Channel in case of P2P Search
10274 if it is set in ini file
10275 */
10276 if(cfg_param->skipDfsChnlInP2pSearch)
10277 {
10278 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010279 }
10280 else
10281 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010282 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010284
Agarwal Ashish4f616132013-12-30 23:32:50 +053010285 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010286 }
10287 }
10288
10289 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10290
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010291 /* acquire the wakelock to avoid the apps suspend during the scan. To
10292 * address the following issues.
10293 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10294 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10295 * for long time, this result in apps running at full power for long time.
10296 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10297 * be stuck in full power because of resume BMPS
10298 */
10299 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010300
Nirav Shah20ac06f2013-12-12 18:14:06 +053010301 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10302 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010303 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10304 scanRequest.requestType, scanRequest.scanType,
10305 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010306 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10307
Siddharth Bhal76972212014-10-15 16:22:51 +053010308 if (pHddCtx->spoofMacAddr.isEnabled)
10309 {
10310 hddLog(VOS_TRACE_LEVEL_INFO,
10311 "%s: MAC Spoofing enabled for current scan", __func__);
10312 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10313 * to fill TxBds for probe request during current scan
10314 */
10315 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10316 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10317 }
10318
Jeff Johnsone7245742012-09-05 17:12:55 -070010319 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 pAdapter->sessionId, &scanRequest, &scanId,
10321 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010322
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 if (eHAL_STATUS_SUCCESS != status)
10324 {
10325 hddLog(VOS_TRACE_LEVEL_ERROR,
10326 "%s: sme_ScanRequest returned error %d", __func__, status);
10327 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010328 if(eHAL_STATUS_RESOURCES == status)
10329 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10331 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010332 status = -EBUSY;
10333 } else {
10334 status = -EIO;
10335 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010336 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 goto free_mem;
10338 }
10339
10340 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010341 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 pAdapter->request = request;
10343 pScanInfo->scanId = scanId;
10344
10345 complete(&pScanInfo->scan_req_completion_event);
10346
10347free_mem:
10348 if( scanRequest.SSIDs.SSIDList )
10349 {
10350 vos_mem_free(scanRequest.SSIDs.SSIDList);
10351 }
10352
10353 if( channelList )
10354 vos_mem_free( channelList );
10355
10356 EXIT();
10357
10358 return status;
10359}
10360
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010361int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10362#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10363 struct net_device *dev,
10364#endif
10365 struct cfg80211_scan_request *request)
10366{
10367 int ret;
10368
10369 vos_ssr_protect(__func__);
10370 ret = __wlan_hdd_cfg80211_scan(wiphy,
10371#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10372 dev,
10373#endif
10374 request);
10375 vos_ssr_unprotect(__func__);
10376
10377 return ret;
10378}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010379
10380void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10381{
10382 v_U8_t iniDot11Mode =
10383 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10384 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10385
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010386 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10387 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010388 switch ( iniDot11Mode )
10389 {
10390 case eHDD_DOT11_MODE_AUTO:
10391 case eHDD_DOT11_MODE_11ac:
10392 case eHDD_DOT11_MODE_11ac_ONLY:
10393#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010394 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10395 sme_IsFeatureSupportedByFW(DOT11AC) )
10396 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10397 else
10398 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010399#else
10400 hddDot11Mode = eHDD_DOT11_MODE_11n;
10401#endif
10402 break;
10403 case eHDD_DOT11_MODE_11n:
10404 case eHDD_DOT11_MODE_11n_ONLY:
10405 hddDot11Mode = eHDD_DOT11_MODE_11n;
10406 break;
10407 default:
10408 hddDot11Mode = iniDot11Mode;
10409 break;
10410 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010411#ifdef WLAN_FEATURE_AP_HT40_24G
10412 if (operationChannel > SIR_11B_CHANNEL_END)
10413#endif
10414 {
10415 /* This call decides required channel bonding mode */
10416 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010417 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10418 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010419 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010420}
10421
Jeff Johnson295189b2012-06-20 16:38:30 -070010422/*
10423 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010426int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010427 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010428{
10429 int status = 0;
10430 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010431 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 v_U32_t roamId;
10433 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 eCsrAuthType RSNAuthType;
10435
10436 ENTER();
10437
10438 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010439 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10440
10441 status = wlan_hdd_validate_context(pHddCtx);
10442 if (status)
10443 {
10444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10445 "%s: HDD context is not valid!", __func__);
10446 return status;
10447 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010448
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10450 {
10451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10452 return -EINVAL;
10453 }
10454
10455 pRoamProfile = &pWextState->roamProfile;
10456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010457 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010459 hdd_station_ctx_t *pHddStaCtx;
10460 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010461
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010462 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10464 {
10465 /*QoS not enabled in cfg file*/
10466 pRoamProfile->uapsd_mask = 0;
10467 }
10468 else
10469 {
10470 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010471 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10473 }
10474
10475 pRoamProfile->SSIDs.numOfSSIDs = 1;
10476 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10477 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10480 ssid, ssid_len);
10481
10482 if (bssid)
10483 {
10484 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10485 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10486 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010487 /* Save BSSID in seperate variable as well, as RoamProfile
10488 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 case of join failure we should send valid BSSID to supplicant
10490 */
10491 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10492 WNI_CFG_BSSID_LEN);
10493 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010494 else
10495 {
10496 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10497 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010498
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010499 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10500 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10502 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010503 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010504 /*set gen ie*/
10505 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10506 /*set auth*/
10507 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010509#ifdef FEATURE_WLAN_WAPI
10510 if (pAdapter->wapi_info.nWapiMode)
10511 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010512 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 switch (pAdapter->wapi_info.wapiAuthMode)
10514 {
10515 case WAPI_AUTH_MODE_PSK:
10516 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010517 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 pAdapter->wapi_info.wapiAuthMode);
10519 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10520 break;
10521 }
10522 case WAPI_AUTH_MODE_CERT:
10523 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010524 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 pAdapter->wapi_info.wapiAuthMode);
10526 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10527 break;
10528 }
10529 } // End of switch
10530 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10531 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10532 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010533 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 pRoamProfile->AuthType.numEntries = 1;
10535 pRoamProfile->EncryptionType.numEntries = 1;
10536 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10537 pRoamProfile->mcEncryptionType.numEntries = 1;
10538 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10539 }
10540 }
10541#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010542#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010543 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010544 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10545 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10546 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010547 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10548 sizeof (tSirGtkOffloadParams));
10549 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010550 }
10551#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 pRoamProfile->csrPersona = pAdapter->device_mode;
10553
Jeff Johnson32d95a32012-09-10 13:15:23 -070010554 if( operatingChannel )
10555 {
10556 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10557 pRoamProfile->ChannelInfo.numOfChannels = 1;
10558 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010559 else
10560 {
10561 pRoamProfile->ChannelInfo.ChannelList = NULL;
10562 pRoamProfile->ChannelInfo.numOfChannels = 0;
10563 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010564 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10565 {
10566 hdd_select_cbmode(pAdapter,operatingChannel);
10567 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010568
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010569 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10570 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010571 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010572 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010573 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10574 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010575 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10576 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010577 {
10578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10579 "%s: Set HDD connState to eConnectionState_Connecting",
10580 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010581 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10582 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010583 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010584 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 pAdapter->sessionId, pRoamProfile, &roamId);
10586
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010587 if ((eHAL_STATUS_SUCCESS != status) &&
10588 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10589 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010590
10591 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10593 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10594 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010595 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010596 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010597 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010598
10599 pRoamProfile->ChannelInfo.ChannelList = NULL;
10600 pRoamProfile->ChannelInfo.numOfChannels = 0;
10601
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 }
10603 else
10604 {
10605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10606 return -EINVAL;
10607 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010608 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 return status;
10610}
10611
10612/*
10613 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10614 * This function is used to set the authentication type (OPEN/SHARED).
10615 *
10616 */
10617static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10618 enum nl80211_auth_type auth_type)
10619{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010620 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10622
10623 ENTER();
10624
10625 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010626 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010628 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010629 hddLog(VOS_TRACE_LEVEL_INFO,
10630 "%s: set authentication type to AUTOSWITCH", __func__);
10631 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10632 break;
10633
10634 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010635#ifdef WLAN_FEATURE_VOWIFI_11R
10636 case NL80211_AUTHTYPE_FT:
10637#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 "%s: set authentication type to OPEN", __func__);
10640 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10641 break;
10642
10643 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010644 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010645 "%s: set authentication type to SHARED", __func__);
10646 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10647 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010648#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010649 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010650 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010651 "%s: set authentication type to CCKM WPA", __func__);
10652 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10653 break;
10654#endif
10655
10656
10657 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010658 hddLog(VOS_TRACE_LEVEL_ERROR,
10659 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010660 auth_type);
10661 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10662 return -EINVAL;
10663 }
10664
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010665 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010666 pHddStaCtx->conn_info.authType;
10667 return 0;
10668}
10669
10670/*
10671 * FUNCTION: wlan_hdd_set_akm_suite
10672 * This function is used to set the key mgmt type(PSK/8021x).
10673 *
10674 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010675static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 u32 key_mgmt
10677 )
10678{
10679 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10680 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010681 /* Should be in ieee802_11_defs.h */
10682#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10683#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010684 /*set key mgmt type*/
10685 switch(key_mgmt)
10686 {
10687 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010688 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010689#ifdef WLAN_FEATURE_VOWIFI_11R
10690 case WLAN_AKM_SUITE_FT_PSK:
10691#endif
10692 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 __func__);
10694 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10695 break;
10696
10697 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010698 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010699#ifdef WLAN_FEATURE_VOWIFI_11R
10700 case WLAN_AKM_SUITE_FT_8021X:
10701#endif
10702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 __func__);
10704 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10705 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010706#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010707#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10708#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10709 case WLAN_AKM_SUITE_CCKM:
10710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10711 __func__);
10712 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10713 break;
10714#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010715#ifndef WLAN_AKM_SUITE_OSEN
10716#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10717 case WLAN_AKM_SUITE_OSEN:
10718 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10719 __func__);
10720 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10721 break;
10722#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010723
10724 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 __func__, key_mgmt);
10727 return -EINVAL;
10728
10729 }
10730 return 0;
10731}
10732
10733/*
10734 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010735 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010736 * (NONE/WEP40/WEP104/TKIP/CCMP).
10737 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010738static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10739 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010740 bool ucast
10741 )
10742{
10743 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010744 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10746
10747 ENTER();
10748
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 __func__, cipher);
10753 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10754 }
10755 else
10756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010759 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 {
10761 case IW_AUTH_CIPHER_NONE:
10762 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10763 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010764
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010766 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010768
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010770 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010771 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 case WLAN_CIPHER_SUITE_TKIP:
10774 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10775 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010776
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 case WLAN_CIPHER_SUITE_CCMP:
10778 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10779 break;
10780#ifdef FEATURE_WLAN_WAPI
10781 case WLAN_CIPHER_SUITE_SMS4:
10782 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10783 break;
10784#endif
10785
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010786#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010787 case WLAN_CIPHER_SUITE_KRK:
10788 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10789 break;
10790#endif
10791 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010793 __func__, cipher);
10794 return -EOPNOTSUPP;
10795 }
10796 }
10797
10798 if (ucast)
10799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 __func__, encryptionType);
10802 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10803 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010804 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 encryptionType;
10806 }
10807 else
10808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010810 __func__, encryptionType);
10811 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10812 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10813 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10814 }
10815
10816 return 0;
10817}
10818
10819
10820/*
10821 * FUNCTION: wlan_hdd_cfg80211_set_ie
10822 * This function is used to parse WPA/RSN IE's.
10823 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010824int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10825 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 size_t ie_len
10827 )
10828{
10829 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10830 u8 *genie = ie;
10831 v_U16_t remLen = ie_len;
10832#ifdef FEATURE_WLAN_WAPI
10833 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10834 u16 *tmp;
10835 v_U16_t akmsuiteCount;
10836 int *akmlist;
10837#endif
10838 ENTER();
10839
10840 /* clear previous assocAddIE */
10841 pWextState->assocAddIE.length = 0;
10842 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010843 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010844
10845 while (remLen >= 2)
10846 {
10847 v_U16_t eLen = 0;
10848 v_U8_t elementId;
10849 elementId = *genie++;
10850 eLen = *genie++;
10851 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010852
Arif Hussain6d2a3322013-11-17 19:50:10 -080010853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855
10856 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010857 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010858 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010859 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 -070010860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010861 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010862 "%s: Invalid WPA IE", __func__);
10863 return -EINVAL;
10864 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010865 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 {
10867 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010870
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10872 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010873 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10874 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 VOS_ASSERT(0);
10876 return -ENOMEM;
10877 }
10878 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10879 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10880 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010881
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10883 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10884 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10885 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010886 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10887 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10889 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10890 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10891 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10892 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10893 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010894 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010895 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 {
10897 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010898 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010900
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10902 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010903 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10904 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 VOS_ASSERT(0);
10906 return -ENOMEM;
10907 }
10908 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10909 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10910 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010911
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10913 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010915#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010916 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10917 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010918 /*Consider WFD IE, only for P2P Client */
10919 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10920 {
10921 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10926 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010927 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10928 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 VOS_ASSERT(0);
10930 return -ENOMEM;
10931 }
10932 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10933 // WPS IE + P2P IE + WFD IE
10934 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10935 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010936
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10938 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10939 }
10940#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010941 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010943 HS20_OUI_TYPE_SIZE)) )
10944 {
10945 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010946 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010947 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010948
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010949 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10950 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010951 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10952 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010953 VOS_ASSERT(0);
10954 return -ENOMEM;
10955 }
10956 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10957 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010958
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010959 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10960 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10961 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010962 /* Appending OSEN Information Element in Assiciation Request */
10963 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10964 OSEN_OUI_TYPE_SIZE)) )
10965 {
10966 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10967 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10968 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010969
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010970 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10971 {
10972 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10973 "Need bigger buffer space");
10974 VOS_ASSERT(0);
10975 return -ENOMEM;
10976 }
10977 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10978 pWextState->assocAddIE.length += eLen + 2;
10979
10980 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10981 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10982 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10983 }
10984
10985 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010986 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10987
10988 /* populating as ADDIE in beacon frames */
10989 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10991 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10992 {
10993 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10994 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10995 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10996 {
10997 hddLog(LOGE,
10998 "Coldn't pass "
10999 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11000 }
11001 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11002 else
11003 hddLog(LOGE,
11004 "Could not pass on "
11005 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11006
11007 /* IBSS mode doesn't contain params->proberesp_ies still
11008 beaconIE's need to be populated in probe response frames */
11009 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11010 {
11011 u16 rem_probe_resp_ie_len = eLen + 2;
11012 u8 probe_rsp_ie_len[3] = {0};
11013 u8 counter = 0;
11014
11015 /* Check Probe Resp Length if it is greater then 255 then
11016 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11017 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11018 not able Store More then 255 bytes into One Variable */
11019
11020 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11021 {
11022 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11023 {
11024 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11025 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11026 }
11027 else
11028 {
11029 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11030 rem_probe_resp_ie_len = 0;
11031 }
11032 }
11033
11034 rem_probe_resp_ie_len = 0;
11035
11036 if (probe_rsp_ie_len[0] > 0)
11037 {
11038 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11039 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11040 (tANI_U8*)(genie - 2),
11041 probe_rsp_ie_len[0], NULL,
11042 eANI_BOOLEAN_FALSE)
11043 == eHAL_STATUS_FAILURE)
11044 {
11045 hddLog(LOGE,
11046 "Could not pass"
11047 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11048 }
11049 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11050 }
11051
11052 if (probe_rsp_ie_len[1] > 0)
11053 {
11054 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11055 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11056 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11057 probe_rsp_ie_len[1], NULL,
11058 eANI_BOOLEAN_FALSE)
11059 == eHAL_STATUS_FAILURE)
11060 {
11061 hddLog(LOGE,
11062 "Could not pass"
11063 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11064 }
11065 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11066 }
11067
11068 if (probe_rsp_ie_len[2] > 0)
11069 {
11070 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11071 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11072 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11073 probe_rsp_ie_len[2], NULL,
11074 eANI_BOOLEAN_FALSE)
11075 == eHAL_STATUS_FAILURE)
11076 {
11077 hddLog(LOGE,
11078 "Could not pass"
11079 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11080 }
11081 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11082 }
11083
11084 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11085 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11086 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11087 {
11088 hddLog(LOGE,
11089 "Could not pass"
11090 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11091 }
11092 }
11093 else
11094 {
11095 // Reset WNI_CFG_PROBE_RSP Flags
11096 wlan_hdd_reset_prob_rspies(pAdapter);
11097
11098 hddLog(VOS_TRACE_LEVEL_INFO,
11099 "%s: No Probe Response IE received in set beacon",
11100 __func__);
11101 }
11102 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011103 break;
11104 case DOT11F_EID_RSN:
11105 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11106 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11107 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11108 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11109 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11110 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011111 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11112 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011113 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011114 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011115 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011116 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011117
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011118 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11119 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011120 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11121 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011122 VOS_ASSERT(0);
11123 return -ENOMEM;
11124 }
11125 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11126 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011128 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11129 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11130 break;
11131 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011132#ifdef FEATURE_WLAN_WAPI
11133 case WLAN_EID_WAPI:
11134 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011135 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011136 pAdapter->wapi_info.nWapiMode);
11137 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011138 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 akmsuiteCount = WPA_GET_LE16(tmp);
11140 tmp = tmp + 1;
11141 akmlist = (int *)(tmp);
11142 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11143 {
11144 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11145 }
11146 else
11147 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011148 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 VOS_ASSERT(0);
11150 return -EINVAL;
11151 }
11152
11153 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11154 {
11155 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011156 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011162 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11164 }
11165 break;
11166#endif
11167 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011168 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011170 /* when Unknown IE is received we should break and continue
11171 * to the next IE in the buffer instead we were returning
11172 * so changing this to break */
11173 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 }
11175 genie += eLen;
11176 remLen -= eLen;
11177 }
11178 EXIT();
11179 return 0;
11180}
11181
11182/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011183 * FUNCTION: hdd_isWPAIEPresent
11184 * Parse the received IE to find the WPA IE
11185 *
11186 */
11187static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11188{
11189 v_U8_t eLen = 0;
11190 v_U16_t remLen = ie_len;
11191 v_U8_t elementId = 0;
11192
11193 while (remLen >= 2)
11194 {
11195 elementId = *ie++;
11196 eLen = *ie++;
11197 remLen -= 2;
11198 if (eLen > remLen)
11199 {
11200 hddLog(VOS_TRACE_LEVEL_ERROR,
11201 "%s: IE length is wrong %d", __func__, eLen);
11202 return FALSE;
11203 }
11204 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11205 {
11206 /* OUI - 0x00 0X50 0XF2
11207 WPA Information Element - 0x01
11208 WPA version - 0x01*/
11209 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11210 return TRUE;
11211 }
11212 ie += eLen;
11213 remLen -= eLen;
11214 }
11215 return FALSE;
11216}
11217
11218/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011220 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011221 * parameters during connect operation.
11222 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011223int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 struct cfg80211_connect_params *req
11225 )
11226{
11227 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011228 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 ENTER();
11230
11231 /*set wpa version*/
11232 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11233
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011234 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011236 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 {
11238 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11239 }
11240 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11241 {
11242 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11243 }
11244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011245
11246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 pWextState->wpaVersion);
11248
11249 /*set authentication type*/
11250 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11251
11252 if (0 > status)
11253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011254 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 "%s: failed to set authentication type ", __func__);
11256 return status;
11257 }
11258
11259 /*set key mgmt type*/
11260 if (req->crypto.n_akm_suites)
11261 {
11262 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11263 if (0 > status)
11264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 __func__);
11267 return status;
11268 }
11269 }
11270
11271 /*set pairwise cipher type*/
11272 if (req->crypto.n_ciphers_pairwise)
11273 {
11274 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11275 req->crypto.ciphers_pairwise[0], true);
11276 if (0 > status)
11277 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011278 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 "%s: failed to set unicast cipher type", __func__);
11280 return status;
11281 }
11282 }
11283 else
11284 {
11285 /*Reset previous cipher suite to none*/
11286 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11287 if (0 > status)
11288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 "%s: failed to set unicast cipher type", __func__);
11291 return status;
11292 }
11293 }
11294
11295 /*set group cipher type*/
11296 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11297 false);
11298
11299 if (0 > status)
11300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 __func__);
11303 return status;
11304 }
11305
Chet Lanctot186b5732013-03-18 10:26:30 -070011306#ifdef WLAN_FEATURE_11W
11307 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11308#endif
11309
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11311 if (req->ie_len)
11312 {
11313 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11314 if ( 0 > status)
11315 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 __func__);
11318 return status;
11319 }
11320 }
11321
11322 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011323 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 {
11325 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11326 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11327 )
11328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 __func__);
11334 return -EOPNOTSUPP;
11335 }
11336 else
11337 {
11338 u8 key_len = req->key_len;
11339 u8 key_idx = req->key_idx;
11340
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011341 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 && (CSR_MAX_NUM_KEY > key_idx)
11343 )
11344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011345 hddLog(VOS_TRACE_LEVEL_INFO,
11346 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 __func__, key_idx, key_len);
11348 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011349 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011351 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 (u8)key_len;
11353 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11354 }
11355 }
11356 }
11357 }
11358
11359 return status;
11360}
11361
11362/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011363 * FUNCTION: wlan_hdd_try_disconnect
11364 * This function is used to disconnect from previous
11365 * connection
11366 */
11367static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11368{
11369 long ret = 0;
11370 hdd_station_ctx_t *pHddStaCtx;
11371 eMib_dot11DesiredBssType connectedBssType;
11372
11373 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11374
11375 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11376
11377 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11378 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11379 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11380 {
11381 /* Issue disconnect to CSR */
11382 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11383 if( eHAL_STATUS_SUCCESS ==
11384 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11385 pAdapter->sessionId,
11386 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11387 {
11388 ret = wait_for_completion_interruptible_timeout(
11389 &pAdapter->disconnect_comp_var,
11390 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11391 if (0 >= ret)
11392 {
11393 hddLog(LOGE, FL("Failed to receive disconnect event"));
11394 return -EALREADY;
11395 }
11396 }
11397 }
11398 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11399 {
11400 ret = wait_for_completion_interruptible_timeout(
11401 &pAdapter->disconnect_comp_var,
11402 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11403 if (0 >= ret)
11404 {
11405 hddLog(LOGE, FL("Failed to receive disconnect event"));
11406 return -EALREADY;
11407 }
11408 }
11409
11410 return 0;
11411}
11412
11413/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011414 * FUNCTION: __wlan_hdd_cfg80211_connect
11415 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011417static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 struct net_device *ndev,
11419 struct cfg80211_connect_params *req
11420 )
11421{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011422 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011425 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011426
11427 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011428
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011429 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11430 TRACE_CODE_HDD_CFG80211_CONNECT,
11431 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011432 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011433 "%s: device_mode = %s (%d)", __func__,
11434 hdd_device_modetoString(pAdapter->device_mode),
11435 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011436
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011438 if (!pHddCtx)
11439 {
11440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11441 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011442 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011443 }
11444
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011445 status = wlan_hdd_validate_context(pHddCtx);
11446
11447 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11450 "%s: HDD context is not valid", __func__);
11451 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011452 }
11453
Agarwal Ashish51325b52014-06-16 16:50:49 +053011454 if (vos_max_concurrent_connections_reached()) {
11455 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11456 return -ECONNREFUSED;
11457 }
11458
Jeff Johnson295189b2012-06-20 16:38:30 -070011459#ifdef WLAN_BTAMP_FEATURE
11460 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011465 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 }
11467#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011468
11469 //If Device Mode is Station Concurrent Sessions Exit BMps
11470 //P2P Mode will be taken care in Open/close adapter
11471 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011472 (vos_concurrent_open_sessions_running())) {
11473 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11474 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011475 }
11476
11477 /*Try disconnecting if already in connected state*/
11478 status = wlan_hdd_try_disconnect(pAdapter);
11479 if ( 0 > status)
11480 {
11481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11482 " connection"));
11483 return -EALREADY;
11484 }
11485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011487 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011488
11489 if ( 0 > status)
11490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 __func__);
11493 return status;
11494 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011495 if ( req->channel )
11496 {
11497 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11498 req->ssid_len, req->bssid,
11499 req->channel->hw_value);
11500 }
11501 else
11502 {
11503 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011504 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011506
11507 if (0 > status)
11508 {
11509 //ReEnable BMPS if disabled
11510 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11511 (NULL != pHddCtx))
11512 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011513 if (pHddCtx->hdd_wlan_suspended)
11514 {
11515 hdd_set_pwrparams(pHddCtx);
11516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 //ReEnable Bmps and Imps back
11518 hdd_enable_bmps_imps(pHddCtx);
11519 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 return status;
11522 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011523 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 EXIT();
11525 return status;
11526}
11527
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011528static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11529 struct net_device *ndev,
11530 struct cfg80211_connect_params *req)
11531{
11532 int ret;
11533 vos_ssr_protect(__func__);
11534 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11535 vos_ssr_unprotect(__func__);
11536
11537 return ret;
11538}
Jeff Johnson295189b2012-06-20 16:38:30 -070011539
11540/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011541 * FUNCTION: wlan_hdd_disconnect
11542 * This function is used to issue a disconnect request to SME
11543 */
11544int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11545{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011546 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011547 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011549 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011550
11551 status = wlan_hdd_validate_context(pHddCtx);
11552
11553 if (0 != status)
11554 {
11555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11556 "%s: HDD context is not valid", __func__);
11557 return status;
11558 }
11559
11560 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011561
Agarwal Ashish47d18112014-08-04 19:55:07 +053011562 /* Need to apply spin lock before decreasing active sessions
11563 * as there can be chance for double decrement if context switch
11564 * Calls hdd_DisConnectHandler.
11565 */
11566
11567 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011568 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11569 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011570 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11571 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011572 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11573 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011574
Abhishek Singhf4669da2014-05-26 15:07:49 +053011575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011576 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11577
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011578 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011579
Mihir Shete182a0b22014-08-18 16:08:48 +053011580 /*
11581 * stop tx queues before deleting STA/BSS context from the firmware.
11582 * tx has to be disabled because the firmware can get busy dropping
11583 * the tx frames after BSS/STA has been deleted and will not send
11584 * back a response resulting in WDI timeout
11585 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011587 netif_tx_disable(pAdapter->dev);
11588 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011589
Mihir Shete182a0b22014-08-18 16:08:48 +053011590 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011591 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11592 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011593 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11594 {
11595 hddLog(VOS_TRACE_LEVEL_INFO,
11596 FL("status = %d, already disconnected"),
11597 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011598
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011599 }
11600 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011601 {
11602 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011603 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011604 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011605 result = -EINVAL;
11606 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011607 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011608 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011609 &pAdapter->disconnect_comp_var,
11610 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011611 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011612 {
11613 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011614 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011615 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011616 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011617 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011618 {
11619 hddLog(VOS_TRACE_LEVEL_ERROR,
11620 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011621 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011622 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011623disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11625 FL("Set HDD connState to eConnectionState_NotConnected"));
11626 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11627
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011628 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011629}
11630
11631
11632/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011633 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 * This function is used to issue a disconnect request to SME
11635 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011636static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 struct net_device *dev,
11638 u16 reason
11639 )
11640{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642 tCsrRoamProfile *pRoamProfile =
11643 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011644 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11646 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011647#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011648 tANI_U8 staIdx;
11649#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011650
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011652
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011653 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11654 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11655 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011656 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11657 __func__, hdd_device_modetoString(pAdapter->device_mode),
11658 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011659
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011660 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11661 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011662
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011663 status = wlan_hdd_validate_context(pHddCtx);
11664
11665 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11668 "%s: HDD context is not valid", __func__);
11669 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011671
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 if (NULL != pRoamProfile)
11673 {
11674 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011675 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11676 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011680 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 switch(reason)
11682 {
11683 case WLAN_REASON_MIC_FAILURE:
11684 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11685 break;
11686
11687 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11688 case WLAN_REASON_DISASSOC_AP_BUSY:
11689 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11690 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11691 break;
11692
11693 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11694 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011695 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11697 break;
11698
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 default:
11700 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11701 break;
11702 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011703 pScanInfo = &pHddCtx->scan_info;
11704 if (pScanInfo->mScanPending)
11705 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011706 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011707 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011708 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011709 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011710 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011711
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011712#ifdef FEATURE_WLAN_TDLS
11713 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011714 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011715 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011716 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11717 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011718 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011719 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011720 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011721 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011722 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011723 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011724 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011725 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011726 pAdapter->sessionId,
11727 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011728 }
11729 }
11730#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011731 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011732 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11733 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 {
11735 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011736 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 __func__, (int)status );
11738 return -EINVAL;
11739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011741 else
11742 {
11743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11744 "called while in %d state", __func__,
11745 pHddStaCtx->conn_info.connState);
11746 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 }
11748 else
11749 {
11750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11751 }
11752
11753 return status;
11754}
11755
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011756static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11757 struct net_device *dev,
11758 u16 reason
11759 )
11760{
11761 int ret;
11762 vos_ssr_protect(__func__);
11763 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11764 vos_ssr_unprotect(__func__);
11765
11766 return ret;
11767}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011768
Jeff Johnson295189b2012-06-20 16:38:30 -070011769/*
11770 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011771 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 * settings in IBSS mode.
11773 */
11774static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011775 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 struct cfg80211_ibss_params *params
11777 )
11778{
11779 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11782 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011783
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 ENTER();
11785
11786 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011787 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011788
11789 if (params->ie_len && ( NULL != params->ie) )
11790 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011791 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11792 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 {
11794 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11795 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11796 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011797 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011799 tDot11fIEWPA dot11WPAIE;
11800 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011801 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011802
Wilson Yang00256342013-10-10 23:13:38 -070011803 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011804 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11805 params->ie_len, DOT11F_EID_WPA);
11806 if ( NULL != ie )
11807 {
11808 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11809 // Unpack the WPA IE
11810 //Skip past the EID byte and length byte - and four byte WiFi OUI
11811 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11812 &ie[2+4],
11813 ie[1] - 4,
11814 &dot11WPAIE);
11815 /*Extract the multicast cipher, the encType for unicast
11816 cipher for wpa-none is none*/
11817 encryptionType =
11818 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11819 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011821
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11823
11824 if (0 > status)
11825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011827 __func__);
11828 return status;
11829 }
11830 }
11831
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832 pWextState->roamProfile.AuthType.authType[0] =
11833 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11835
11836 if (params->privacy)
11837 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011838 /* Security enabled IBSS, At this time there is no information available
11839 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011843 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 *enable privacy bit in beacons */
11845
11846 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11847 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011848 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11849 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11851 pWextState->roamProfile.EncryptionType.numEntries = 1;
11852 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 return status;
11854}
11855
11856/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011857 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011860static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 struct net_device *dev,
11862 struct cfg80211_ibss_params *params
11863 )
11864{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11867 tCsrRoamProfile *pRoamProfile;
11868 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011869 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011870 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11871 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011872
11873 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011874
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011875 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11876 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11877 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011878 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011879 "%s: device_mode = %s (%d)", __func__,
11880 hdd_device_modetoString(pAdapter->device_mode),
11881 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011882
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011883 status = wlan_hdd_validate_context(pHddCtx);
11884
11885 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11888 "%s: HDD context is not valid", __func__);
11889 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 }
11891
11892 if (NULL == pWextState)
11893 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011894 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011895 __func__);
11896 return -EIO;
11897 }
11898
Agarwal Ashish51325b52014-06-16 16:50:49 +053011899 if (vos_max_concurrent_connections_reached()) {
11900 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11901 return -ECONNREFUSED;
11902 }
11903
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011904 /*Try disconnecting if already in connected state*/
11905 status = wlan_hdd_try_disconnect(pAdapter);
11906 if ( 0 > status)
11907 {
11908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11909 " IBSS connection"));
11910 return -EALREADY;
11911 }
11912
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 pRoamProfile = &pWextState->roamProfile;
11914
11915 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011917 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011918 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 return -EINVAL;
11920 }
11921
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011922 /* BSSID is provided by upper layers hence no need to AUTO generate */
11923 if (NULL != params->bssid) {
11924 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11925 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11926 hddLog (VOS_TRACE_LEVEL_ERROR,
11927 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11928 return -EIO;
11929 }
11930 }
krunal sonie9002db2013-11-25 14:24:17 -080011931 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11932 {
11933 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11934 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11935 {
11936 hddLog (VOS_TRACE_LEVEL_ERROR,
11937 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11938 return -EIO;
11939 }
11940 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11941 if (!params->bssid)
11942 {
11943 hddLog (VOS_TRACE_LEVEL_ERROR,
11944 "%s:Failed memory allocation", __func__);
11945 return -EIO;
11946 }
11947 vos_mem_copy((v_U8_t *)params->bssid,
11948 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11949 VOS_MAC_ADDR_SIZE);
11950 alloc_bssid = VOS_TRUE;
11951 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011952
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011954 if (NULL !=
11955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11956 params->chandef.chan)
11957#else
11958 params->channel)
11959#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 {
11961 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011962 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11963 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11964 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11965 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011966
11967 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011968 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011969 ieee80211_frequency_to_channel(
11970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11971 params->chandef.chan->center_freq);
11972#else
11973 params->channel->center_freq);
11974#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011975
11976 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11977 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11980 __func__);
11981 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011983
11984 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011986 if (channelNum == validChan[indx])
11987 {
11988 break;
11989 }
11990 }
11991 if (indx >= numChans)
11992 {
11993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 __func__, channelNum);
11995 return -EINVAL;
11996 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011997 /* Set the Operational Channel */
11998 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11999 channelNum);
12000 pRoamProfile->ChannelInfo.numOfChannels = 1;
12001 pHddStaCtx->conn_info.operationChannel = channelNum;
12002 pRoamProfile->ChannelInfo.ChannelList =
12003 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 }
12005
12006 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 if (status < 0)
12009 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 __func__);
12012 return status;
12013 }
12014
12015 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012016 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012017 params->ssid_len, params->bssid,
12018 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012019
12020 if (0 > status)
12021 {
12022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12023 return status;
12024 }
12025
krunal sonie9002db2013-11-25 14:24:17 -080012026 if (NULL != params->bssid &&
12027 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12028 alloc_bssid == VOS_TRUE)
12029 {
12030 vos_mem_free(params->bssid);
12031 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012032 return 0;
12033}
12034
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012035static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12036 struct net_device *dev,
12037 struct cfg80211_ibss_params *params
12038 )
12039{
12040 int ret = 0;
12041
12042 vos_ssr_protect(__func__);
12043 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12044 vos_ssr_unprotect(__func__);
12045
12046 return ret;
12047}
12048
Jeff Johnson295189b2012-06-20 16:38:30 -070012049/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012050 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012051 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012053static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012054 struct net_device *dev
12055 )
12056{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012058 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12059 tCsrRoamProfile *pRoamProfile;
12060 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012061 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012062
12063 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012064
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012065 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12066 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12067 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012068 status = wlan_hdd_validate_context(pHddCtx);
12069
12070 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12073 "%s: HDD context is not valid", __func__);
12074 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012075 }
12076
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012077 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12078 hdd_device_modetoString(pAdapter->device_mode),
12079 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 if (NULL == pWextState)
12081 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012082 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 __func__);
12084 return -EIO;
12085 }
12086
12087 pRoamProfile = &pWextState->roamProfile;
12088
12089 /* Issue disconnect only if interface type is set to IBSS */
12090 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 __func__);
12094 return -EINVAL;
12095 }
12096
12097 /* Issue Disconnect request */
12098 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12099 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12100 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12101
12102 return 0;
12103}
12104
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012105static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12106 struct net_device *dev
12107 )
12108{
12109 int ret = 0;
12110
12111 vos_ssr_protect(__func__);
12112 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12113 vos_ssr_unprotect(__func__);
12114
12115 return ret;
12116}
12117
Jeff Johnson295189b2012-06-20 16:38:30 -070012118/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012119 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 * This function is used to set the phy parameters
12121 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12122 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012123static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 u32 changed)
12125{
12126 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12127 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012128 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012129
12130 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12132 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12133 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012134 status = wlan_hdd_validate_context(pHddCtx);
12135
12136 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012137 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12139 "%s: HDD context is not valid", __func__);
12140 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012141 }
12142
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12144 {
12145 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12146 WNI_CFG_RTS_THRESHOLD_STAMAX :
12147 wiphy->rts_threshold;
12148
12149 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012150 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012152 hddLog(VOS_TRACE_LEVEL_ERROR,
12153 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 __func__, rts_threshold);
12155 return -EINVAL;
12156 }
12157
12158 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12159 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012160 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012162 hddLog(VOS_TRACE_LEVEL_ERROR,
12163 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 __func__, rts_threshold);
12165 return -EIO;
12166 }
12167
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 rts_threshold);
12170 }
12171
12172 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12173 {
12174 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12175 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12176 wiphy->frag_threshold;
12177
12178 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012181 hddLog(VOS_TRACE_LEVEL_ERROR,
12182 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 frag_threshold);
12184 return -EINVAL;
12185 }
12186
12187 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12188 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012189 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012191 hddLog(VOS_TRACE_LEVEL_ERROR,
12192 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 __func__, frag_threshold);
12194 return -EIO;
12195 }
12196
12197 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12198 frag_threshold);
12199 }
12200
12201 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12202 || (changed & WIPHY_PARAM_RETRY_LONG))
12203 {
12204 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12205 wiphy->retry_short :
12206 wiphy->retry_long;
12207
12208 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12209 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12210 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 __func__, retry_value);
12213 return -EINVAL;
12214 }
12215
12216 if (changed & WIPHY_PARAM_RETRY_SHORT)
12217 {
12218 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12219 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012220 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012222 hddLog(VOS_TRACE_LEVEL_ERROR,
12223 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 __func__, retry_value);
12225 return -EIO;
12226 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012227 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 __func__, retry_value);
12229 }
12230 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12231 {
12232 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12233 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012236 hddLog(VOS_TRACE_LEVEL_ERROR,
12237 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 __func__, retry_value);
12239 return -EIO;
12240 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 __func__, retry_value);
12243 }
12244 }
12245
12246 return 0;
12247}
12248
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012249static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12250 u32 changed)
12251{
12252 int ret;
12253
12254 vos_ssr_protect(__func__);
12255 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12256 vos_ssr_unprotect(__func__);
12257
12258 return ret;
12259}
12260
Jeff Johnson295189b2012-06-20 16:38:30 -070012261/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012262 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 * This function is used to set the txpower
12264 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012265static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012266#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12267 struct wireless_dev *wdev,
12268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012269#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012270 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012271#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012273#endif
12274 int dbm)
12275{
12276 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012277 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12279 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012280 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012281
12282 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012283 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12284 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12285 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012286 status = wlan_hdd_validate_context(pHddCtx);
12287
12288 if (0 != status)
12289 {
12290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12291 "%s: HDD context is not valid", __func__);
12292 return status;
12293 }
12294
12295 hHal = pHddCtx->hHal;
12296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12298 dbm, ccmCfgSetCallback,
12299 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012301 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12303 return -EIO;
12304 }
12305
12306 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12307 dbm);
12308
12309 switch(type)
12310 {
12311 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12312 /* Fall through */
12313 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12314 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12315 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12317 __func__);
12318 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 }
12320 break;
12321 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 __func__);
12324 return -EOPNOTSUPP;
12325 break;
12326 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12328 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 return -EIO;
12330 }
12331
12332 return 0;
12333}
12334
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012335static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12336#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12337 struct wireless_dev *wdev,
12338#endif
12339#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12340 enum tx_power_setting type,
12341#else
12342 enum nl80211_tx_power_setting type,
12343#endif
12344 int dbm)
12345{
12346 int ret;
12347 vos_ssr_protect(__func__);
12348 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12349#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12350 wdev,
12351#endif
12352#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12353 type,
12354#else
12355 type,
12356#endif
12357 dbm);
12358 vos_ssr_unprotect(__func__);
12359
12360 return ret;
12361}
12362
Jeff Johnson295189b2012-06-20 16:38:30 -070012363/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012364 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 * This function is used to read the txpower
12366 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012367static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012368#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12369 struct wireless_dev *wdev,
12370#endif
12371 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012372{
12373
12374 hdd_adapter_t *pAdapter;
12375 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012376 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012377
Jeff Johnsone7245742012-09-05 17:12:55 -070012378 ENTER();
12379
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012380 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012381
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012382 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012383 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12385 "%s: HDD context is not valid", __func__);
12386 *dbm = 0;
12387 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012388 }
12389
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12391 if (NULL == pAdapter)
12392 {
12393 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12394 return -ENOENT;
12395 }
12396
12397 wlan_hdd_get_classAstats(pAdapter);
12398 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12399
Jeff Johnsone7245742012-09-05 17:12:55 -070012400 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 return 0;
12402}
12403
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012404static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12405#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12406 struct wireless_dev *wdev,
12407#endif
12408 int *dbm)
12409{
12410 int ret;
12411
12412 vos_ssr_protect(__func__);
12413 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12414#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12415 wdev,
12416#endif
12417 dbm);
12418 vos_ssr_unprotect(__func__);
12419
12420 return ret;
12421}
12422
12423
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012424static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 u8* mac, struct station_info *sinfo)
12426{
12427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12428 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12429 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012430 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
12432 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12433 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012434
12435 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12436 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12437 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12438 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12439 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12440 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12441 tANI_U16 maxRate = 0;
12442 tANI_U16 myRate;
12443 tANI_U16 currentRate = 0;
12444 tANI_U8 maxSpeedMCS = 0;
12445 tANI_U8 maxMCSIdx = 0;
12446 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012447 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012448 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012449 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012450
Leo Chang6f8870f2013-03-26 18:11:36 -070012451#ifdef WLAN_FEATURE_11AC
12452 tANI_U32 vht_mcs_map;
12453 eDataRate11ACMaxMcs vhtMaxMcs;
12454#endif /* WLAN_FEATURE_11AC */
12455
Jeff Johnsone7245742012-09-05 17:12:55 -070012456 ENTER();
12457
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12459 (0 == ssidlen))
12460 {
12461 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12462 " Invalid ssidlen, %d", __func__, ssidlen);
12463 /*To keep GUI happy*/
12464 return 0;
12465 }
12466
Mukul Sharma811205f2014-07-09 21:07:30 +053012467 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12468 {
12469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12470 "%s: Roaming in progress, so unable to proceed this request", __func__);
12471 return 0;
12472 }
12473
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012474 status = wlan_hdd_validate_context(pHddCtx);
12475
12476 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012477 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12479 "%s: HDD context is not valid", __func__);
12480 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012481 }
12482
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
Kiet Lam3b17fc82013-09-27 05:24:08 +053012484 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12485 sinfo->filled |= STATION_INFO_SIGNAL;
12486
c_hpothu09f19542014-05-30 21:53:31 +053012487 wlan_hdd_get_station_stats(pAdapter);
12488 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12489
12490 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012491 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12492 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012493 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012494 {
12495 rate_flags = pAdapter->maxRateFlags;
12496 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012497
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 //convert to the UI units of 100kbps
12499 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12500
12501#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012502 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 -070012503 sinfo->signal,
12504 pCfg->reportMaxLinkSpeed,
12505 myRate,
12506 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012507 (int) pCfg->linkSpeedRssiMid,
12508 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012509 (int) rate_flags,
12510 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012511#endif //LINKSPEED_DEBUG_ENABLED
12512
12513 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12514 {
12515 // we do not want to necessarily report the current speed
12516 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12517 {
12518 // report the max possible speed
12519 rssidx = 0;
12520 }
12521 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12522 {
12523 // report the max possible speed with RSSI scaling
12524 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12525 {
12526 // report the max possible speed
12527 rssidx = 0;
12528 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012529 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 {
12531 // report middle speed
12532 rssidx = 1;
12533 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012534 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12535 {
12536 // report middle speed
12537 rssidx = 2;
12538 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 else
12540 {
12541 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012542 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012543 }
12544 }
12545 else
12546 {
12547 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12548 hddLog(VOS_TRACE_LEVEL_ERROR,
12549 "%s: Invalid value for reportMaxLinkSpeed: %u",
12550 __func__, pCfg->reportMaxLinkSpeed);
12551 rssidx = 0;
12552 }
12553
12554 maxRate = 0;
12555
12556 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012557 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12558 OperationalRates, &ORLeng))
12559 {
12560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12561 /*To keep GUI happy*/
12562 return 0;
12563 }
12564
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 for (i = 0; i < ORLeng; i++)
12566 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012567 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 {
12569 /* Validate Rate Set */
12570 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12571 {
12572 currentRate = supported_data_rate[j].supported_rate[rssidx];
12573 break;
12574 }
12575 }
12576 /* Update MAX rate */
12577 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12578 }
12579
12580 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012581 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12582 ExtendedRates, &ERLeng))
12583 {
12584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12585 /*To keep GUI happy*/
12586 return 0;
12587 }
12588
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 for (i = 0; i < ERLeng; i++)
12590 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012591 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 {
12593 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12594 {
12595 currentRate = supported_data_rate[j].supported_rate[rssidx];
12596 break;
12597 }
12598 }
12599 /* Update MAX rate */
12600 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12601 }
c_hpothu79aab322014-07-14 21:11:01 +053012602
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012603 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012604 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012605 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012606 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 {
c_hpothu79aab322014-07-14 21:11:01 +053012608 if (rate_flags & eHAL_TX_RATE_VHT80)
12609 mode = 2;
12610 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12611 mode = 1;
12612 else
12613 mode = 0;
12614
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012615 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12616 MCSRates, &MCSLeng))
12617 {
12618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12619 /*To keep GUI happy*/
12620 return 0;
12621 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012623#ifdef WLAN_FEATURE_11AC
12624 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012625 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012627 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012628 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012629 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012631 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012633 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012634 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012635 maxMCSIdx = 7;
12636 }
12637 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12638 {
12639 maxMCSIdx = 8;
12640 }
12641 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12642 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012643 //VHT20 is supporting 0~8
12644 if (rate_flags & eHAL_TX_RATE_VHT20)
12645 maxMCSIdx = 8;
12646 else
12647 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012648 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012649
c_hpothu79aab322014-07-14 21:11:01 +053012650 if (0 != rssidx)/*check for scaled */
12651 {
12652 //get middle rate MCS index if rssi=1/2
12653 for (i=0; i <= maxMCSIdx; i++)
12654 {
12655 if (sinfo->signal <= rssiMcsTbl[mode][i])
12656 {
12657 maxMCSIdx = i;
12658 break;
12659 }
12660 }
12661 }
12662
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012663 if (rate_flags & eHAL_TX_RATE_VHT80)
12664 {
12665 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12666 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12667 }
12668 else if (rate_flags & eHAL_TX_RATE_VHT40)
12669 {
12670 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12671 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12672 }
12673 else if (rate_flags & eHAL_TX_RATE_VHT20)
12674 {
12675 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12676 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12677 }
12678
Leo Chang6f8870f2013-03-26 18:11:36 -070012679 maxSpeedMCS = 1;
12680 if (currentRate > maxRate)
12681 {
12682 maxRate = currentRate;
12683 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012684
Leo Chang6f8870f2013-03-26 18:11:36 -070012685 }
12686 else
12687#endif /* WLAN_FEATURE_11AC */
12688 {
12689 if (rate_flags & eHAL_TX_RATE_HT40)
12690 {
12691 rateFlag |= 1;
12692 }
12693 if (rate_flags & eHAL_TX_RATE_SGI)
12694 {
12695 rateFlag |= 2;
12696 }
12697
Girish Gowli01abcee2014-07-31 20:18:55 +053012698 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012699 if (rssidx == 1 || rssidx == 2)
12700 {
12701 //get middle rate MCS index if rssi=1/2
12702 for (i=0; i <= 7; i++)
12703 {
12704 if (sinfo->signal <= rssiMcsTbl[mode][i])
12705 {
12706 temp = i+1;
12707 break;
12708 }
12709 }
12710 }
c_hpothu79aab322014-07-14 21:11:01 +053012711
12712 for (i = 0; i < MCSLeng; i++)
12713 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012714 for (j = 0; j < temp; j++)
12715 {
12716 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12717 {
12718 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12719 break;
12720 }
12721 }
12722 if ((j < temp) && (currentRate > maxRate))
12723 {
12724 maxRate = currentRate;
12725 maxSpeedMCS = 1;
12726 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 }
12729 }
12730 }
12731
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012732 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12733 {
12734 maxRate = myRate;
12735 maxSpeedMCS = 1;
12736 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12737 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012739 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 {
12741 maxRate = myRate;
12742 if (rate_flags & eHAL_TX_RATE_LEGACY)
12743 {
12744 maxSpeedMCS = 0;
12745 }
12746 else
12747 {
12748 maxSpeedMCS = 1;
12749 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12750 }
12751 }
12752
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012753 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012754 {
12755 sinfo->txrate.legacy = maxRate;
12756#ifdef LINKSPEED_DEBUG_ENABLED
12757 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12758#endif //LINKSPEED_DEBUG_ENABLED
12759 }
12760 else
12761 {
12762 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012763#ifdef WLAN_FEATURE_11AC
12764 sinfo->txrate.nss = 1;
12765 if (rate_flags & eHAL_TX_RATE_VHT80)
12766 {
12767 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012768 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012769 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012770 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012771 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012772 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12773 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12774 }
12775 else if (rate_flags & eHAL_TX_RATE_VHT20)
12776 {
12777 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12778 }
12779#endif /* WLAN_FEATURE_11AC */
12780 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12781 {
12782 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12783 if (rate_flags & eHAL_TX_RATE_HT40)
12784 {
12785 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12786 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012787 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 if (rate_flags & eHAL_TX_RATE_SGI)
12789 {
12790 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12791 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012792
Jeff Johnson295189b2012-06-20 16:38:30 -070012793#ifdef LINKSPEED_DEBUG_ENABLED
12794 pr_info("Reporting MCS rate %d flags %x\n",
12795 sinfo->txrate.mcs,
12796 sinfo->txrate.flags );
12797#endif //LINKSPEED_DEBUG_ENABLED
12798 }
12799 }
12800 else
12801 {
12802 // report current rate instead of max rate
12803
12804 if (rate_flags & eHAL_TX_RATE_LEGACY)
12805 {
12806 //provide to the UI in units of 100kbps
12807 sinfo->txrate.legacy = myRate;
12808#ifdef LINKSPEED_DEBUG_ENABLED
12809 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12810#endif //LINKSPEED_DEBUG_ENABLED
12811 }
12812 else
12813 {
12814 //must be MCS
12815 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012816#ifdef WLAN_FEATURE_11AC
12817 sinfo->txrate.nss = 1;
12818 if (rate_flags & eHAL_TX_RATE_VHT80)
12819 {
12820 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12821 }
12822 else
12823#endif /* WLAN_FEATURE_11AC */
12824 {
12825 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12826 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012827 if (rate_flags & eHAL_TX_RATE_SGI)
12828 {
12829 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12830 }
12831 if (rate_flags & eHAL_TX_RATE_HT40)
12832 {
12833 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12834 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012835#ifdef WLAN_FEATURE_11AC
12836 else if (rate_flags & eHAL_TX_RATE_VHT80)
12837 {
12838 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12839 }
12840#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012841#ifdef LINKSPEED_DEBUG_ENABLED
12842 pr_info("Reporting actual MCS rate %d flags %x\n",
12843 sinfo->txrate.mcs,
12844 sinfo->txrate.flags );
12845#endif //LINKSPEED_DEBUG_ENABLED
12846 }
12847 }
12848 sinfo->filled |= STATION_INFO_TX_BITRATE;
12849
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012850 sinfo->tx_packets =
12851 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12852 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12853 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12854 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12855
12856 sinfo->tx_retries =
12857 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12858 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12859 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12860 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12861
12862 sinfo->tx_failed =
12863 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12864 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12865 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12866 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12867
12868 sinfo->filled |=
12869 STATION_INFO_TX_PACKETS |
12870 STATION_INFO_TX_RETRIES |
12871 STATION_INFO_TX_FAILED;
12872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12874 TRACE_CODE_HDD_CFG80211_GET_STA,
12875 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012876 EXIT();
12877 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012878}
12879
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012880static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12881 u8* mac, struct station_info *sinfo)
12882{
12883 int ret;
12884
12885 vos_ssr_protect(__func__);
12886 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12887 vos_ssr_unprotect(__func__);
12888
12889 return ret;
12890}
12891
12892static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012893 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012894{
12895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012896 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012898 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012899
Jeff Johnsone7245742012-09-05 17:12:55 -070012900 ENTER();
12901
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 if (NULL == pAdapter)
12903 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 return -ENODEV;
12906 }
12907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12909 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12910 pAdapter->sessionId, timeout));
12911
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012915 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012916 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12918 "%s: HDD context is not valid", __func__);
12919 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012920 }
12921
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012922 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12923 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12924 (pHddCtx->cfg_ini->fhostArpOffload) &&
12925 (eConnectionState_Associated ==
12926 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12927 {
Amar Singhald53568e2013-09-26 11:03:45 -070012928
12929 hddLog(VOS_TRACE_LEVEL_INFO,
12930 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012931 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012932 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12933 {
12934 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012935 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012936 __func__, vos_status);
12937 }
12938 }
12939
Jeff Johnson295189b2012-06-20 16:38:30 -070012940 /**The get power cmd from the supplicant gets updated by the nl only
12941 *on successful execution of the function call
12942 *we are oppositely mapped w.r.t mode in the driver
12943 **/
12944 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12945
Jeff Johnsone7245742012-09-05 17:12:55 -070012946 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 if (VOS_STATUS_E_FAILURE == vos_status)
12948 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12950 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 return -EINVAL;
12952 }
12953 return 0;
12954}
12955
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012956static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12957 struct net_device *dev, bool mode, int timeout)
12958{
12959 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012960
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012961 vos_ssr_protect(__func__);
12962 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12963 vos_ssr_unprotect(__func__);
12964
12965 return ret;
12966}
Jeff Johnson295189b2012-06-20 16:38:30 -070012967#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012968static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12969 struct net_device *netdev,
12970 u8 key_index)
12971{
12972 ENTER();
12973 return 0;
12974}
12975
Jeff Johnson295189b2012-06-20 16:38:30 -070012976static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012977 struct net_device *netdev,
12978 u8 key_index)
12979{
12980 int ret;
12981 vos_ssr_protect(__func__);
12982 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12983 vos_ssr_unprotect(__func__);
12984 return ret;
12985}
12986#endif //LINUX_VERSION_CODE
12987
12988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12989static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12990 struct net_device *dev,
12991 struct ieee80211_txq_params *params)
12992{
12993 ENTER();
12994 return 0;
12995}
12996#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12997static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12998 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012999{
Jeff Johnsone7245742012-09-05 17:12:55 -070013000 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013001 return 0;
13002}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013003#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013004
13005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13006static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013007 struct net_device *dev,
13008 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013009{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013010 int ret;
13011
13012 vos_ssr_protect(__func__);
13013 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13014 vos_ssr_unprotect(__func__);
13015 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013016}
13017#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13018static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13019 struct ieee80211_txq_params *params)
13020{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013021 int ret;
13022
13023 vos_ssr_protect(__func__);
13024 ret = __wlan_hdd_set_txq_params(wiphy, params);
13025 vos_ssr_unprotect(__func__);
13026 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013027}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013029
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013030static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013031 struct net_device *dev,
13032 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013033{
13034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013035 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013036 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013037 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013038 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013039 v_CONTEXT_t pVosContext = NULL;
13040 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013041 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013043 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 return -EINVAL;
13047 }
13048
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013049 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13050 TRACE_CODE_HDD_CFG80211_DEL_STA,
13051 pAdapter->sessionId, pAdapter->device_mode));
13052
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13054 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013055
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013056 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13059 "%s: HDD context is not valid", __func__);
13060 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013061 }
13062
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 )
13066 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013067 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13068 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13069 if(pSapCtx == NULL){
13070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13071 FL("psapCtx is NULL"));
13072 return -ENOENT;
13073 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013074 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 {
13076 v_U16_t i;
13077 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13078 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013079 if ((pSapCtx->aStaInfo[i].isUsed) &&
13080 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013082 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013083 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013084 ETHER_ADDR_LEN);
13085
Jeff Johnson295189b2012-06-20 16:38:30 -070013086 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013087 "%s: Delete STA with MAC::"
13088 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013089 __func__,
13090 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13091 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013092 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013093 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 }
13095 }
13096 }
13097 else
13098 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013099
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013100 vos_status = hdd_softap_GetStaId(pAdapter,
13101 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013102 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13103 {
13104 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013105 "%s: Skip this DEL STA as this is not used::"
13106 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013107 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013108 return -ENOENT;
13109 }
13110
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013111 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013112 {
13113 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013114 "%s: Skip this DEL STA as deauth is in progress::"
13115 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013116 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013117 return -ENOENT;
13118 }
13119
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013120 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013121
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 hddLog(VOS_TRACE_LEVEL_INFO,
13123 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013124 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013125 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013126 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013127
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013128 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013129 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13130 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013131 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013132 hddLog(VOS_TRACE_LEVEL_INFO,
13133 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013134 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013135 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013136 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013137 return -ENOENT;
13138 }
13139
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 }
13141 }
13142
13143 EXIT();
13144
13145 return 0;
13146}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013147
13148#ifdef CFG80211_DEL_STA_V2
13149static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13150 struct net_device *dev,
13151 struct station_del_parameters *param)
13152#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013153static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13154 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013155#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013156{
13157 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013158 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013159
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013160 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013161
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013162#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013163 if (NULL == param) {
13164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013165 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013166 return -EINVAL;
13167 }
13168
13169 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13170 param->subtype, &delStaParams);
13171
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013172#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013173 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013174 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013175#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013176 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13177
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013178 vos_ssr_unprotect(__func__);
13179
13180 return ret;
13181}
13182
13183static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013184 struct net_device *dev, u8 *mac, struct station_parameters *params)
13185{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013187 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013188#ifdef FEATURE_WLAN_TDLS
13189 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013190 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13193 TRACE_CODE_HDD_CFG80211_ADD_STA,
13194 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013195 mask = params->sta_flags_mask;
13196
13197 set = params->sta_flags_set;
13198
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013199#ifdef WLAN_FEATURE_TDLS_DEBUG
13200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13201 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13202 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13203#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013204
13205 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13206 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013207 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013208 }
13209 }
13210#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013211 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013212}
13213
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013214static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13215 struct net_device *dev, u8 *mac, struct station_parameters *params)
13216{
13217 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013218
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013219 vos_ssr_protect(__func__);
13220 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13221 vos_ssr_unprotect(__func__);
13222
13223 return ret;
13224}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013225#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013226
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013227static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013228 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013229{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13231 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013232 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013233 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013234 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013235 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013236
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013237 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013238 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013241 return -EINVAL;
13242 }
13243
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013244 if (!pmksa) {
13245 hddLog(LOGE, FL("pmksa is NULL"));
13246 return -EINVAL;
13247 }
13248
13249 if (!pmksa->bssid || !pmksa->pmkid) {
13250 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13251 pmksa->bssid, pmksa->pmkid);
13252 return -EINVAL;
13253 }
13254
13255 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13256 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13257
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013258 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13259 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013260
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013261 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013262 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13264 "%s: HDD context is not valid", __func__);
13265 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013266 }
13267
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013269 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13270
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013271 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13272 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013273
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013274 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013275 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013276 &pmk_id, 1, FALSE);
13277
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013278 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13279 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13280 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013281
13282 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013283}
13284
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013285static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13286 struct cfg80211_pmksa *pmksa)
13287{
13288 int ret;
13289
13290 vos_ssr_protect(__func__);
13291 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13292 vos_ssr_unprotect(__func__);
13293
13294 return ret;
13295}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013296
Wilson Yang6507c4e2013-10-01 20:11:19 -070013297
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013298static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013299 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013300{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13302 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013303 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013304 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013305
Wilson Yang6507c4e2013-10-01 20:11:19 -070013306 /* Validate pAdapter */
13307 if (NULL == pAdapter)
13308 {
13309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13310 return -EINVAL;
13311 }
13312
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013313 if (!pmksa) {
13314 hddLog(LOGE, FL("pmksa is NULL"));
13315 return -EINVAL;
13316 }
13317
13318 if (!pmksa->bssid) {
13319 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13320 return -EINVAL;
13321 }
13322
Kiet Lam98c46a12014-10-31 15:34:57 -070013323 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13324 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13325
Wilson Yang6507c4e2013-10-01 20:11:19 -070013326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13327 status = wlan_hdd_validate_context(pHddCtx);
13328
13329 if (0 != status)
13330 {
13331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13332 "%s: HDD context is not valid", __func__);
13333 return status;
13334 }
13335
13336 /*Retrieve halHandle*/
13337 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13338
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013339 /* Delete the PMKID CSR cache */
13340 if (eHAL_STATUS_SUCCESS !=
13341 sme_RoamDelPMKIDfromCache(halHandle,
13342 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13343 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13344 MAC_ADDR_ARRAY(pmksa->bssid));
13345 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013346 }
13347
Wilson Yangef657d32014-01-15 19:19:23 -080013348 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013349}
13350
Wilson Yang6507c4e2013-10-01 20:11:19 -070013351
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013352static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13353 struct cfg80211_pmksa *pmksa)
13354{
13355 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013356
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013357 vos_ssr_protect(__func__);
13358 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13359 vos_ssr_unprotect(__func__);
13360
13361 return ret;
13362
13363}
13364
13365static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013366{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013367 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13368 tHalHandle halHandle;
13369 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013370 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013371
13372 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13373
13374 /* Validate pAdapter */
13375 if (NULL == pAdapter)
13376 {
13377 hddLog(VOS_TRACE_LEVEL_ERROR,
13378 "%s: Invalid Adapter" ,__func__);
13379 return -EINVAL;
13380 }
13381
13382 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13383 status = wlan_hdd_validate_context(pHddCtx);
13384
13385 if (0 != status)
13386 {
13387 hddLog(VOS_TRACE_LEVEL_ERROR,
13388 "%s: HDD context is not valid", __func__);
13389 return status;
13390 }
13391
13392 /*Retrieve halHandle*/
13393 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13394
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013395 /* Flush the PMKID cache in CSR */
13396 if (eHAL_STATUS_SUCCESS !=
13397 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13399 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013400 }
13401
Wilson Yangef657d32014-01-15 19:19:23 -080013402 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013403}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013404
13405static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13406{
13407 int ret;
13408
13409 vos_ssr_protect(__func__);
13410 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13411 vos_ssr_unprotect(__func__);
13412
13413 return ret;
13414}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013415#endif
13416
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013417#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013418static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13419 struct net_device *dev,
13420 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013421{
13422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13423 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013424 hdd_context_t *pHddCtx;
13425 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013426
13427 if (NULL == pAdapter)
13428 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013430 return -ENODEV;
13431 }
13432
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013433 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13434 ret = wlan_hdd_validate_context(pHddCtx);
13435 if (0 != ret)
13436 {
13437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13438 "%s: HDD context is not valid", __func__);
13439 return ret;
13440 }
13441
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013442 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13443
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013444 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13445 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13446 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013447 // Added for debug on reception of Re-assoc Req.
13448 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13449 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013450 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013451 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013452 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013453 }
13454
13455#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013456 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013457 ftie->ie_len);
13458#endif
13459
13460 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013461 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13462 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013463 ftie->ie_len);
13464 return 0;
13465}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013466
13467static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13468 struct net_device *dev,
13469 struct cfg80211_update_ft_ies_params *ftie)
13470{
13471 int ret;
13472
13473 vos_ssr_protect(__func__);
13474 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13475 vos_ssr_unprotect(__func__);
13476
13477 return ret;
13478}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013479#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013480
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013481#ifdef FEATURE_WLAN_SCAN_PNO
13482
13483void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13484 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13485{
13486 int ret;
13487 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13488 hdd_context_t *pHddCtx;
13489
Nirav Shah80830bf2013-12-31 16:35:12 +053013490 ENTER();
13491
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013492 if (NULL == pAdapter)
13493 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013495 "%s: HDD adapter is Null", __func__);
13496 return ;
13497 }
13498
13499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13500 if (NULL == pHddCtx)
13501 {
13502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13503 "%s: HDD context is Null!!!", __func__);
13504 return ;
13505 }
13506
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013507 spin_lock(&pHddCtx->schedScan_lock);
13508 if (TRUE == pHddCtx->isWiphySuspended)
13509 {
13510 pHddCtx->isSchedScanUpdatePending = TRUE;
13511 spin_unlock(&pHddCtx->schedScan_lock);
13512 hddLog(VOS_TRACE_LEVEL_INFO,
13513 "%s: Update cfg80211 scan database after it resume", __func__);
13514 return ;
13515 }
13516 spin_unlock(&pHddCtx->schedScan_lock);
13517
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013518 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13519
13520 if (0 > ret)
13521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13522
13523 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13525 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013526}
13527
13528/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013529 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013530 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013531 */
13532static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13533{
13534 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13535 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013536 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013537 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13538 int status = 0;
13539 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13540
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013541 /* The current firmware design does not allow PNO during any
13542 * active sessions. Hence, determine the active sessions
13543 * and return a failure.
13544 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013545 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13546 {
13547 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013548 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013549
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013550 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13551 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13552 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13553 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13554 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013555 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013556 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013557 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013558 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013559 }
13560 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13561 pAdapterNode = pNext;
13562 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013563 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013564}
13565
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013566void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13567{
13568 hdd_adapter_t *pAdapter = callbackContext;
13569 hdd_context_t *pHddCtx;
13570
13571 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13572 {
13573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13574 FL("Invalid adapter or adapter has invalid magic"));
13575 return;
13576 }
13577
13578 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13579 if (0 != wlan_hdd_validate_context(pHddCtx))
13580 {
13581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13582 FL("HDD context is not valid"));
13583 return;
13584 }
13585
c_hpothub53c45d2014-08-18 16:53:14 +053013586 if (VOS_STATUS_SUCCESS != status)
13587 {
13588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013589 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013590 pHddCtx->isPnoEnable = FALSE;
13591 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013592
13593 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13594 complete(&pAdapter->pno_comp_var);
13595}
13596
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013597/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013598 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13599 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013600 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013601static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013602 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13603{
13604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13605 tpSirPNOScanReq pPnoRequest = NULL;
13606 hdd_context_t *pHddCtx;
13607 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013608 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013609 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13610 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013611 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13612 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013613 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013614 hdd_config_t *pConfig = NULL;
13615 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013616
13617 if (NULL == pAdapter)
13618 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013620 "%s: HDD adapter is Null", __func__);
13621 return -ENODEV;
13622 }
13623
13624 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013625 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013626
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013627 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013628 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13630 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013631 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013632 }
13633
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013634 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013635 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13636 if (NULL == hHal)
13637 {
13638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13639 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013640 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013641 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013642 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013643 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013644 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013645 {
13646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13647 "%s: aborting the existing scan is unsuccessfull", __func__);
13648 return -EBUSY;
13649 }
13650
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013651 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013652 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013654 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013655 return -EBUSY;
13656 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013657
c_hpothu37f21312014-04-09 21:49:54 +053013658 if (TRUE == pHddCtx->isPnoEnable)
13659 {
13660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13661 FL("already PNO is enabled"));
13662 return -EBUSY;
13663 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013664
13665 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13666 {
13667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13668 "%s: abort ROC failed ", __func__);
13669 return -EBUSY;
13670 }
13671
c_hpothu37f21312014-04-09 21:49:54 +053013672 pHddCtx->isPnoEnable = TRUE;
13673
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013674 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13675 if (NULL == pPnoRequest)
13676 {
13677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13678 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013679 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013680 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013681 }
13682
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013683 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013684 pPnoRequest->enable = 1; /*Enable PNO */
13685 pPnoRequest->ucNetworksCount = request->n_match_sets;
13686
13687 if (( !pPnoRequest->ucNetworksCount ) ||
13688 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13689 {
13690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013691 "%s: Network input is not correct %d Max Network supported is %d",
13692 __func__, pPnoRequest->ucNetworksCount,
13693 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013694 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013695 goto error;
13696 }
13697
13698 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13699 {
13700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013701 "%s: Incorrect number of channels %d",
13702 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013703 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013704 goto error;
13705 }
13706
13707 /* Framework provides one set of channels(all)
13708 * common for all saved profile */
13709 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13710 channels_allowed, &num_channels_allowed))
13711 {
13712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13713 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013714 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013715 goto error;
13716 }
13717 /* Checking each channel against allowed channel list */
13718 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013719 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013720 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013721 char chList [(request->n_channels*5)+1];
13722 int len;
13723 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013724 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013725 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013726 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013727 if (request->channels[i]->hw_value == channels_allowed[indx])
13728 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013729 if ((!pConfig->enableDFSPnoChnlScan) &&
13730 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13731 {
13732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13733 "%s : Dropping DFS channel : %d",
13734 __func__,channels_allowed[indx]);
13735 num_ignore_dfs_ch++;
13736 break;
13737 }
13738
Nirav Shah80830bf2013-12-31 16:35:12 +053013739 valid_ch[num_ch++] = request->channels[i]->hw_value;
13740 len += snprintf(chList+len, 5, "%d ",
13741 request->channels[i]->hw_value);
13742 break ;
13743 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013744 }
13745 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013746 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013747
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013748 /*If all channels are DFS and dropped, then ignore the PNO request*/
13749 if (num_ignore_dfs_ch == request->n_channels)
13750 {
13751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13752 "%s : All requested channels are DFS channels", __func__);
13753 ret = -EINVAL;
13754 goto error;
13755 }
13756 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013757 /* Filling per profile params */
13758 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13759 {
13760 pPnoRequest->aNetworks[i].ssId.length =
13761 request->match_sets[i].ssid.ssid_len;
13762
13763 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13764 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13765 {
13766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013767 "%s: SSID Len %d is not correct for network %d",
13768 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013769 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013770 goto error;
13771 }
13772
13773 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13774 request->match_sets[i].ssid.ssid,
13775 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13777 "%s: SSID of network %d is %s ", __func__,
13778 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013779 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13780 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13781 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13782
13783 /*Copying list of valid channel into request */
13784 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13785 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13786
13787 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13788 }
13789
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013790 for (i = 0; i < request->n_ssids; i++)
13791 {
13792 j = 0;
13793 while (j < pPnoRequest->ucNetworksCount)
13794 {
13795 if ((pPnoRequest->aNetworks[j].ssId.length ==
13796 request->ssids[i].ssid_len) &&
13797 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13798 request->ssids[i].ssid,
13799 pPnoRequest->aNetworks[j].ssId.length)))
13800 {
13801 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13802 break;
13803 }
13804 j++;
13805 }
13806 }
13807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13808 "Number of hidden networks being Configured = %d",
13809 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013811 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013812 if ((0 < request->ie_len) && (NULL != request->ie))
13813 {
13814 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13815 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13816 pPnoRequest->us24GProbeTemplateLen);
13817
13818 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13819 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13820 pPnoRequest->us5GProbeTemplateLen);
13821 }
13822
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013823 /* Driver gets only one time interval which is hardcoded in
13824 * supplicant for 10000ms. Taking power consumption into account 6 timers
13825 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13826 * 80,160,320 secs. And number of scan cycle for each timer
13827 * is configurable through INI param gPNOScanTimerRepeatValue.
13828 * If it is set to 0 only one timer will be used and PNO scan cycle
13829 * will be repeated after each interval specified by supplicant
13830 * till PNO is disabled.
13831 */
13832 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13833 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13834 else
13835 pPnoRequest->scanTimers.ucScanTimersCount =
13836 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13837
13838 tempInterval = (request->interval)/1000;
13839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13840 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13841 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13842 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13843 {
13844 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13845 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13846 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13847 tempInterval *= 2;
13848 }
13849 //Repeat last timer until pno disabled.
13850 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13851
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013852 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013853
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013854 INIT_COMPLETION(pAdapter->pno_comp_var);
13855 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13856 pPnoRequest->callbackContext = pAdapter;
13857 pAdapter->pno_req_status = 0;
13858
Nirav Shah80830bf2013-12-31 16:35:12 +053013859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13860 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13861 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13862 pPnoRequest->scanTimers.ucScanTimersCount);
13863
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013864 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13865 pPnoRequest, pAdapter->sessionId,
13866 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13867 if (eHAL_STATUS_SUCCESS != status)
13868 {
13869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013870 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013871 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013872 goto error;
13873 }
13874
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013875 ret = wait_for_completion_timeout(
13876 &pAdapter->pno_comp_var,
13877 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13878 if (0 >= ret)
13879 {
13880 // Did not receive the response for PNO enable in time.
13881 // Assuming the PNO enable was success.
13882 // Returning error from here, because we timeout, results
13883 // in side effect of Wifi (Wifi Setting) not to work.
13884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13885 FL("Timed out waiting for PNO to be Enabled"));
13886 ret = 0;
13887 goto error;
13888 }
13889
c_hpothu3c986b22014-07-09 14:45:09 +053013890 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013891 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013892 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013893
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013894error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13896 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013897 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013898 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013899 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013900}
13901
13902/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013903 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13904 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013905 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013906static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13907 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13908{
13909 int ret;
13910
13911 vos_ssr_protect(__func__);
13912 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13913 vos_ssr_unprotect(__func__);
13914
13915 return ret;
13916}
13917
13918/*
13919 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13920 * Function to disable PNO
13921 */
13922static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013923 struct net_device *dev)
13924{
13925 eHalStatus status = eHAL_STATUS_FAILURE;
13926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13927 hdd_context_t *pHddCtx;
13928 tHalHandle hHal;
13929 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013930 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013931
13932 ENTER();
13933
13934 if (NULL == pAdapter)
13935 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013937 "%s: HDD adapter is Null", __func__);
13938 return -ENODEV;
13939 }
13940
13941 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013942
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013943 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013944 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013946 "%s: HDD context is Null", __func__);
13947 return -ENODEV;
13948 }
13949
13950 /* The return 0 is intentional when isLogpInProgress and
13951 * isLoadUnloadInProgress. We did observe a crash due to a return of
13952 * failure in sched_scan_stop , especially for a case where the unload
13953 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13954 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13955 * success. If it returns a failure , then its next invocation due to the
13956 * clean up of the second interface will have the dev pointer corresponding
13957 * to the first one leading to a crash.
13958 */
13959 if (pHddCtx->isLogpInProgress)
13960 {
13961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13962 "%s: LOGP in Progress. Ignore!!!", __func__);
13963 return ret;
13964 }
13965
Mihir Shete18156292014-03-11 15:38:30 +053013966 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013967 {
13968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13969 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13970 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013971 }
13972
13973 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13974 if (NULL == hHal)
13975 {
13976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13977 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013978 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013979 }
13980
13981 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13982 if (NULL == pPnoRequest)
13983 {
13984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13985 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013986 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013987 }
13988
13989 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13990 pPnoRequest->enable = 0; /* Disable PNO */
13991 pPnoRequest->ucNetworksCount = 0;
13992
13993 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13994 pAdapter->sessionId,
13995 NULL, pAdapter);
13996 if (eHAL_STATUS_SUCCESS != status)
13997 {
13998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13999 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014000 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014001 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014002 }
c_hpothu37f21312014-04-09 21:49:54 +053014003 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014004
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014005error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014007 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014008 vos_mem_free(pPnoRequest);
14009
14010 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014011 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014012}
14013
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014014/*
14015 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14016 * NL interface to disable PNO
14017 */
14018static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14019 struct net_device *dev)
14020{
14021 int ret;
14022
14023 vos_ssr_protect(__func__);
14024 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14025 vos_ssr_unprotect(__func__);
14026
14027 return ret;
14028}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014029#endif /*FEATURE_WLAN_SCAN_PNO*/
14030
14031
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014032#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014033#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014034static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014035 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014036 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14037#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014038static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014039 u8 *peer, u8 action_code, u8 dialog_token,
14040 u16 status_code, const u8 *buf, size_t len)
14041#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014042{
14043
14044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14045 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014046 u8 peerMac[6];
14047 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014048 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014049 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014050 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014051 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014052#if !(TDLS_MGMT_VERSION2)
14053 u32 peer_capability = 0;
14054#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014055 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014056
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14058 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14059 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014060 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014063 "Invalid arguments");
14064 return -EINVAL;
14065 }
14066
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014067 if (pHddCtx->isLogpInProgress)
14068 {
14069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14070 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014071 wlan_hdd_tdls_set_link_status(pAdapter,
14072 peer,
14073 eTDLS_LINK_IDLE,
14074 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014075 return -EBUSY;
14076 }
14077
Hoonki Lee27511902013-03-14 18:19:06 -070014078 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014079 {
Hoonki Lee27511902013-03-14 18:19:06 -070014080 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14081 "%s: TDLS mode is disabled OR not enabled in FW."
14082 MAC_ADDRESS_STR " action %d declined.",
14083 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014084 return -ENOTSUPP;
14085 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014086
Hoonki Lee27511902013-03-14 18:19:06 -070014087 /* other than teardown frame, other mgmt frames are not sent if disabled */
14088 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14089 {
14090 /* if tdls_mode is disabled to respond to peer's request */
14091 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14092 {
14093 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14094 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014095 " TDLS mode is disabled. action %d declined.",
14096 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014097
14098 return -ENOTSUPP;
14099 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014100
14101 if (vos_max_concurrent_connections_reached())
14102 {
14103 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14104 return -EINVAL;
14105 }
Hoonki Lee27511902013-03-14 18:19:06 -070014106 }
14107
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014108 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14109 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014110 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014111 {
14112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014113 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014114 " TDLS setup is ongoing. action %d declined.",
14115 __func__, MAC_ADDR_ARRAY(peer), action_code);
14116 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014117 }
14118 }
14119
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014120 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14121 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014122 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014123 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14124 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014125 {
14126 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14127 we return error code at 'add_station()'. Hence we have this
14128 check again in addtion to add_station().
14129 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014130 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014131 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14133 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014134 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14135 __func__, MAC_ADDR_ARRAY(peer), action_code,
14136 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014137 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014138 }
14139 else
14140 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014141 /* maximum reached. tweak to send error code to peer and return
14142 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014143 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14145 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014146 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14147 __func__, MAC_ADDR_ARRAY(peer), status_code,
14148 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014149 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014150 /* fall through to send setup resp with failure status
14151 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014152 }
14153 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014154 else
14155 {
14156 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014157 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014158 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014159 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014161 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14162 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014163 return -EPERM;
14164 }
14165 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014166 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014167 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014168
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014169#ifdef WLAN_FEATURE_TDLS_DEBUG
14170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014171 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014172 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14173 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014174#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014175
Hoonki Leea34dd892013-02-05 22:56:02 -080014176 /*Except teardown responder will not be used so just make 0*/
14177 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014178 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014179 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014180
14181 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014182 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014183
14184 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14185 responder = pTdlsPeer->is_responder;
14186 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014187 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014189 "%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 -070014190 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14191 dialog_token, status_code, len);
14192 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014193 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014194 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014195
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014196 /* For explicit trigger of DIS_REQ come out of BMPS for
14197 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014198 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014199 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14200 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014201 {
14202 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14203 {
14204 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014205 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014206 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14207 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014208 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14209 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014210 }
14211
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014212 /* make sure doesn't call send_mgmt() while it is pending */
14213 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14214 {
14215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014216 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014217 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014218 ret = -EBUSY;
14219 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014220 }
14221
14222 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014223 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14224
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014225 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014226 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014227
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014228 if (VOS_STATUS_SUCCESS != status)
14229 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14231 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014232 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014233 ret = -EINVAL;
14234 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014235 }
14236
Hoonki Leed37cbb32013-04-20 00:31:14 -070014237 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14238 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14239
14240 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014241 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014243 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014244 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014245 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014246
14247 if (pHddCtx->isLogpInProgress)
14248 {
14249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14250 "%s: LOGP in Progress. Ignore!!!", __func__);
14251 return -EAGAIN;
14252 }
14253
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014254 ret = -EINVAL;
14255 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014256 }
14257
Gopichand Nakkala05922802013-03-14 12:23:19 -070014258 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014259 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014260 ret = max_sta_failed;
14261 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014262 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014263
Hoonki Leea34dd892013-02-05 22:56:02 -080014264 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14265 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014266 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014267 }
14268 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14269 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014270 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014271 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014272
14273 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014274
14275tx_failed:
14276 /* add_station will be called before sending TDLS_SETUP_REQ and
14277 * TDLS_SETUP_RSP and as part of add_station driver will enable
14278 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14279 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14280 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14281 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14282 */
14283
14284 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14285 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14286 wlan_hdd_tdls_check_bmps(pAdapter);
14287 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014288}
14289
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014290#if TDLS_MGMT_VERSION2
14291static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14292 u8 *peer, u8 action_code, u8 dialog_token,
14293 u16 status_code, u32 peer_capability,
14294 const u8 *buf, size_t len)
14295#else
14296static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14297 u8 *peer, u8 action_code, u8 dialog_token,
14298 u16 status_code, const u8 *buf, size_t len)
14299#endif
14300{
14301 int ret;
14302
14303 vos_ssr_protect(__func__);
14304#if TDLS_MGMT_VERSION2
14305 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14306 status_code, peer_capability, buf, len);
14307#else
14308 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14309 status_code, buf, len);
14310#endif
14311 vos_ssr_unprotect(__func__);
14312
14313 return ret;
14314}
Atul Mittal115287b2014-07-08 13:26:33 +053014315
14316int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14317 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014318 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014319 cfg80211_exttdls_callback callback)
14320{
14321
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014322 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014323 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14325 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14326 __func__, MAC_ADDR_ARRAY(peer));
14327
14328 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14329 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14330
14331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14332 " %s TDLS External control and Implicit Trigger not enabled ",
14333 __func__);
14334 return -ENOTSUPP;
14335 }
14336
14337 /* To cater the requirement of establishing the TDLS link
14338 * irrespective of the data traffic , get an entry of TDLS peer.
14339 */
14340 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14341 if (pTdlsPeer == NULL) {
14342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14343 "%s: peer " MAC_ADDRESS_STR " not existing",
14344 __func__, MAC_ADDR_ARRAY(peer));
14345 return -EINVAL;
14346 }
14347
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014348 if (NULL != tdls_peer_params)
14349 {
14350 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14351 pTdlsPeer->peerParams.global_operating_class =
14352 tdls_peer_params->global_operating_class;
14353 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14354 pTdlsPeer->peerParams.min_bandwidth_kbps =
14355 tdls_peer_params->min_bandwidth_kbps;
14356 /* check configured channel is valid and non dfs */
14357 if (sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14358 tdls_peer_params->channel))
14359 {
14360 pTdlsPeer->isOffChannelConfigured = TRUE;
14361 }
14362 else
14363 {
14364 pTdlsPeer->isOffChannelConfigured = FALSE;
14365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14366 "%s: Configured Tdls Off Channel is not valid", __func__);
14367
14368 }
14369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14370 "%s: tdls_off_channel %d isOffChannelConfigured %d",
14371 __func__, pTdlsPeer->peerParams.channel,
14372 pTdlsPeer->isOffChannelConfigured);
14373 }
14374 else
14375 {
14376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14377 "%s: Invalid TDLS Peer Params", __func__);
14378 }
14379
Atul Mittal115287b2014-07-08 13:26:33 +053014380 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14381
14382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14383 " %s TDLS Add Force Peer Failed",
14384 __func__);
14385 return -EINVAL;
14386 }
14387 /*EXT TDLS*/
14388
14389 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14391 " %s TDLS set callback Failed",
14392 __func__);
14393 return -EINVAL;
14394 }
14395
14396 return(0);
14397
14398}
14399
14400int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14401{
14402
14403 hddTdlsPeer_t *pTdlsPeer;
14404 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14406 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14407 __func__, MAC_ADDR_ARRAY(peer));
14408
14409 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14410 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14411
14412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14413 " %s TDLS External control and Implicit Trigger not enabled ",
14414 __func__);
14415 return -ENOTSUPP;
14416 }
14417
14418
14419 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14420
14421 if ( NULL == pTdlsPeer ) {
14422 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14423 " peer not exsting",
14424 __func__, MAC_ADDR_ARRAY(peer));
14425 return -EINVAL;
14426 }
14427 else {
14428 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14429 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014430 /* if channel switch is configured, reset
14431 the channel for this peer */
14432 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14433 {
14434 pTdlsPeer->peerParams.channel = 0;
14435 pTdlsPeer->isOffChannelConfigured = FALSE;
14436 }
Atul Mittal115287b2014-07-08 13:26:33 +053014437 }
14438
14439 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14440 return -EINVAL;
14441
14442 /*EXT TDLS*/
14443
14444 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14445
14446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14447 " %s TDLS set callback Failed",
14448 __func__);
14449 return -EINVAL;
14450 }
14451 return(0);
14452
14453}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014454static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014455 u8 *peer, enum nl80211_tdls_operation oper)
14456{
14457 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14458 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014459 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014460 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014461
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014462 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14463 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14464 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014465 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014466 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014468 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014469 return -EINVAL;
14470 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014472 status = wlan_hdd_validate_context(pHddCtx);
14473
14474 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14477 "%s: HDD context is not valid", __func__);
14478 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014479 }
14480
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014481
14482 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014483 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014484 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014486 "TDLS Disabled in INI OR not enabled in FW. "
14487 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014488 return -ENOTSUPP;
14489 }
14490
14491 switch (oper) {
14492 case NL80211_TDLS_ENABLE_LINK:
14493 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014494 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014495 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014496 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014497 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014498 tANI_U16 numCurrTdlsPeers = 0;
14499 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014500
Sunil Dutt41de4e22013-11-14 18:09:02 +053014501 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014502 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014503 if ( NULL == pTdlsPeer ) {
14504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14505 " (oper %d) not exsting. ignored",
14506 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14507 return -EINVAL;
14508 }
14509
14510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14511 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14512 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14513 "NL80211_TDLS_ENABLE_LINK");
14514
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014515 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14516 {
14517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14518 MAC_ADDRESS_STR " failed",
14519 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14520 return -EINVAL;
14521 }
14522
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014523 /* TDLS Off Channel, Disable tdls channel switch,
14524 when there are more than one tdls link */
14525 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14526 if (numCurrTdlsPeers == 1)
14527 {
14528 /* get connected peer and send disable tdls off chan */
14529 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14530 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14531 {
14532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14533 "%s: More then one peer connected, Disable "
14534 "TDLS channel switch", __func__);
14535
14536 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14537 pAdapter->sessionId,
14538 connPeer->peerMac,
14539 connPeer->peerParams.channel,
14540 TDLS_OFF_CHANNEL_BW_OFFSET,
14541 TDLS_CHANNEL_SWITCH_DISABLE);
14542 }
14543 else
14544 {
14545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14546 "%s: No TDLS Connected Peer or "
14547 "isOffChannelConfigured %d",
14548 __func__,
14549 (connPeer ? connPeer->isOffChannelConfigured : -1));
14550 }
14551 }
14552
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014553 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014554 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014555 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014556
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014557 if (0 != wlan_hdd_tdls_get_link_establish_params(
14558 pAdapter, peer,&tdlsLinkEstablishParams)) {
14559 return -EINVAL;
14560 }
14561 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014562
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014563 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14564 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14565 /* Send TDLS peer UAPSD capabilities to the firmware and
14566 * register with the TL on after the response for this operation
14567 * is received .
14568 */
14569 ret = wait_for_completion_interruptible_timeout(
14570 &pAdapter->tdls_link_establish_req_comp,
14571 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14572 if (ret <= 0)
14573 {
14574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14575 "%s: Link Establish Request Faled Status %ld",
14576 __func__, ret);
14577 return -EINVAL;
14578 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014579 }
Atul Mittal115287b2014-07-08 13:26:33 +053014580 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14581 eTDLS_LINK_CONNECTED,
14582 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014583 staDesc.ucSTAId = pTdlsPeer->staId;
14584 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14585 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14586 &staDesc);
14587
14588
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014589 /* Mark TDLS client Authenticated .*/
14590 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14591 pTdlsPeer->staId,
14592 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014593 if (VOS_STATUS_SUCCESS == status)
14594 {
Hoonki Lee14621352013-04-16 17:51:19 -070014595 if (pTdlsPeer->is_responder == 0)
14596 {
14597 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14598
14599 wlan_hdd_tdls_timer_restart(pAdapter,
14600 &pTdlsPeer->initiatorWaitTimeoutTimer,
14601 WAIT_TIME_TDLS_INITIATOR);
14602 /* suspend initiator TX until it receives direct packet from the
14603 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14604 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14605 &staId, NULL);
14606 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014607 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014608
14609 /* TDLS Off Channel, Enable tdls channel switch,
14610 when their is only one tdls link and it supports */
14611 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14612 if ((numCurrTdlsPeers == 1) &&
14613 (TRUE == pTdlsPeer->isOffChannelSupported) &&
14614 (TRUE == pTdlsPeer->isOffChannelConfigured))
14615 {
14616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14617 "%s: Send TDLS channel switch request for channel %d",
14618 __func__, pTdlsPeer->peerParams.channel);
14619 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14620 pAdapter->sessionId,
14621 pTdlsPeer->peerMac,
14622 pTdlsPeer->peerParams.channel,
14623 TDLS_OFF_CHANNEL_BW_OFFSET,
14624 TDLS_CHANNEL_SWITCH_ENABLE);
14625 }
14626 else
14627 {
14628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14629 "%s: TDLS channel switch request not sent"
14630 " numCurrTdlsPeers %d "
14631 "isOffChannelSupported %d "
14632 "isOffChannelConfigured %d",
14633 __func__, numCurrTdlsPeers,
14634 pTdlsPeer->isOffChannelSupported,
14635 pTdlsPeer->isOffChannelConfigured);
14636 }
14637
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014638 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014639 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014640
14641 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014642 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14643 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014644 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014645 int ac;
14646 uint8 ucAc[4] = { WLANTL_AC_VO,
14647 WLANTL_AC_VI,
14648 WLANTL_AC_BK,
14649 WLANTL_AC_BE };
14650 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14651 for(ac=0; ac < 4; ac++)
14652 {
14653 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14654 pTdlsPeer->staId, ucAc[ac],
14655 tlTid[ac], tlTid[ac], 0, 0,
14656 WLANTL_BI_DIR );
14657 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014658 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014659 }
14660
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014661 }
14662 break;
14663 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014664 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014665 tANI_U16 numCurrTdlsPeers = 0;
14666 hddTdlsPeer_t *connPeer = NULL;
14667
Sunil Dutt41de4e22013-11-14 18:09:02 +053014668 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14669
14670 if ( NULL == pTdlsPeer ) {
14671 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14672 " (oper %d) not exsting. ignored",
14673 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14674 return -EINVAL;
14675 }
14676
14677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14678 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14679 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14680 "NL80211_TDLS_DISABLE_LINK");
14681
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014682 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014683 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014684 long status;
14685
Atul Mittal271a7652014-09-12 13:18:22 +053014686
14687 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14688 eTDLS_LINK_TEARING,
14689 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14690 eTDLS_LINK_UNSPECIFIED:
14691 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014692 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14693
Lee Hoonkic1262f22013-01-24 21:59:00 -080014694 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14695 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014696
14697 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14698 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014699 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014700 eTDLS_LINK_IDLE,
14701 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014702 if (status <= 0)
14703 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14705 "%s: Del station failed status %ld",
14706 __func__, status);
14707 return -EPERM;
14708 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014709
14710 /* TDLS Off Channel, Enable tdls channel switch,
14711 when their is only one tdls link and it supports */
14712 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14713 if (numCurrTdlsPeers == 1)
14714 {
14715 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14716 if ((connPeer) &&
14717 (connPeer->isOffChannelSupported == TRUE) &&
14718 (connPeer->isOffChannelConfigured == TRUE))
14719 {
14720 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14721 pAdapter->sessionId,
14722 connPeer->peerMac,
14723 connPeer->peerParams.channel,
14724 TDLS_OFF_CHANNEL_BW_OFFSET,
14725 TDLS_CHANNEL_SWITCH_ENABLE);
14726 }
14727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14728 "%s: TDLS channel switch "
14729 "isOffChannelSupported %d "
14730 "isOffChannelConfigured %d",
14731 __func__,
14732 (connPeer ? connPeer->isOffChannelSupported : -1),
14733 (connPeer ? connPeer->isOffChannelConfigured : -1));
14734 }
14735 else
14736 {
14737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14738 "%s: TDLS channel switch request not sent "
14739 "numCurrTdlsPeers %d ",
14740 __func__, numCurrTdlsPeers);
14741 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014742 }
14743 else
14744 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14746 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014747 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014748 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014749 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014750 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014751 {
Atul Mittal115287b2014-07-08 13:26:33 +053014752 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014753
Atul Mittal115287b2014-07-08 13:26:33 +053014754 if (0 != status)
14755 {
14756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14757 "%s: Error in TDLS Teardown", __func__);
14758 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014759 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014760 break;
14761 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014762 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014763 {
Atul Mittal115287b2014-07-08 13:26:33 +053014764 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14765 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014766 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053014767 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014768
Atul Mittal115287b2014-07-08 13:26:33 +053014769 if (0 != status)
14770 {
14771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14772 "%s: Error in TDLS Setup", __func__);
14773 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014774 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014775 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014776 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014777 case NL80211_TDLS_DISCOVERY_REQ:
14778 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14780 "%s: We don't support in-driver setup/teardown/discovery "
14781 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014782 return -ENOTSUPP;
14783 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14785 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014786 return -ENOTSUPP;
14787 }
14788 return 0;
14789}
Chilam NG571c65a2013-01-19 12:27:36 +053014790
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014791static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14792 u8 *peer, enum nl80211_tdls_operation oper)
14793{
14794 int ret;
14795
14796 vos_ssr_protect(__func__);
14797 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14798 vos_ssr_unprotect(__func__);
14799
14800 return ret;
14801}
14802
Chilam NG571c65a2013-01-19 12:27:36 +053014803int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14804 struct net_device *dev, u8 *peer)
14805{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014806 hddLog(VOS_TRACE_LEVEL_INFO,
14807 "tdls send discover req: "MAC_ADDRESS_STR,
14808 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014809
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014810#if TDLS_MGMT_VERSION2
14811 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14812 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14813#else
Chilam NG571c65a2013-01-19 12:27:36 +053014814 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14815 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014816#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014817}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014818#endif
14819
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014820#ifdef WLAN_FEATURE_GTK_OFFLOAD
14821/*
14822 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14823 * Callback rountine called upon receiving response for
14824 * get offload info
14825 */
14826void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14827 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14828{
14829
14830 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014831 tANI_U8 tempReplayCounter[8];
14832 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014833
14834 ENTER();
14835
14836 if (NULL == pAdapter)
14837 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014839 "%s: HDD adapter is Null", __func__);
14840 return ;
14841 }
14842
14843 if (NULL == pGtkOffloadGetInfoRsp)
14844 {
14845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14846 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14847 return ;
14848 }
14849
14850 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14851 {
14852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14853 "%s: wlan Failed to get replay counter value",
14854 __func__);
14855 return ;
14856 }
14857
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14859 /* Update replay counter */
14860 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14861 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14862
14863 {
14864 /* changing from little to big endian since supplicant
14865 * works on big endian format
14866 */
14867 int i;
14868 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14869
14870 for (i = 0; i < 8; i++)
14871 {
14872 tempReplayCounter[7-i] = (tANI_U8)p[i];
14873 }
14874 }
14875
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014876 /* Update replay counter to NL */
14877 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014878 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014879}
14880
14881/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014882 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014883 * This function is used to offload GTK rekeying job to the firmware.
14884 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014885int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014886 struct cfg80211_gtk_rekey_data *data)
14887{
14888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14889 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14890 hdd_station_ctx_t *pHddStaCtx;
14891 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014892 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014893 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014894 eHalStatus status = eHAL_STATUS_FAILURE;
14895
14896 ENTER();
14897
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014898
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014899 if (NULL == pAdapter)
14900 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014902 "%s: HDD adapter is Null", __func__);
14903 return -ENODEV;
14904 }
14905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14907 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14908 pAdapter->sessionId, pAdapter->device_mode));
14909
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014910 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014911
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014912 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014913 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14915 "%s: HDD context is not valid", __func__);
14916 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014917 }
14918
14919 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14920 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14921 if (NULL == hHal)
14922 {
14923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14924 "%s: HAL context is Null!!!", __func__);
14925 return -EAGAIN;
14926 }
14927
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014928 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14929 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14930 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14931 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014932 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014933 {
14934 /* changing from big to little endian since driver
14935 * works on little endian format
14936 */
14937 tANI_U8 *p =
14938 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14939 int i;
14940
14941 for (i = 0; i < 8; i++)
14942 {
14943 p[7-i] = data->replay_ctr[i];
14944 }
14945 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014946
14947 if (TRUE == pHddCtx->hdd_wlan_suspended)
14948 {
14949 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014950 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14951 sizeof (tSirGtkOffloadParams));
14952 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014953 pAdapter->sessionId);
14954
14955 if (eHAL_STATUS_SUCCESS != status)
14956 {
14957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14958 "%s: sme_SetGTKOffload failed, returned %d",
14959 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014960
14961 /* Need to clear any trace of key value in the memory.
14962 * Thus zero out the memory even though it is local
14963 * variable.
14964 */
14965 vos_mem_zero(&hddGtkOffloadReqParams,
14966 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014967 return status;
14968 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14970 "%s: sme_SetGTKOffload successfull", __func__);
14971 }
14972 else
14973 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14975 "%s: wlan not suspended GTKOffload request is stored",
14976 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014977 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014978
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014979 /* Need to clear any trace of key value in the memory.
14980 * Thus zero out the memory even though it is local
14981 * variable.
14982 */
14983 vos_mem_zero(&hddGtkOffloadReqParams,
14984 sizeof(hddGtkOffloadReqParams));
14985
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014986 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014987}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014988
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014989int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14990 struct cfg80211_gtk_rekey_data *data)
14991{
14992 int ret;
14993
14994 vos_ssr_protect(__func__);
14995 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14996 vos_ssr_unprotect(__func__);
14997
14998 return ret;
14999}
15000#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015001/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015002 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015003 * This function is used to set access control policy
15004 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015005static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15006 struct net_device *dev,
15007 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015008{
15009 int i;
15010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15011 hdd_hostapd_state_t *pHostapdState;
15012 tsap_Config_t *pConfig;
15013 v_CONTEXT_t pVosContext = NULL;
15014 hdd_context_t *pHddCtx;
15015 int status;
15016
15017 ENTER();
15018
15019 if (NULL == pAdapter)
15020 {
15021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15022 "%s: HDD adapter is Null", __func__);
15023 return -ENODEV;
15024 }
15025
15026 if (NULL == params)
15027 {
15028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15029 "%s: params is Null", __func__);
15030 return -EINVAL;
15031 }
15032
15033 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15034 status = wlan_hdd_validate_context(pHddCtx);
15035
15036 if (0 != status)
15037 {
15038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15039 "%s: HDD context is not valid", __func__);
15040 return status;
15041 }
15042
15043 pVosContext = pHddCtx->pvosContext;
15044 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15045
15046 if (NULL == pHostapdState)
15047 {
15048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15049 "%s: pHostapdState is Null", __func__);
15050 return -EINVAL;
15051 }
15052
15053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15054 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15055
15056 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15057 {
15058 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15059
15060 /* default value */
15061 pConfig->num_accept_mac = 0;
15062 pConfig->num_deny_mac = 0;
15063
15064 /**
15065 * access control policy
15066 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15067 * listed in hostapd.deny file.
15068 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15069 * listed in hostapd.accept file.
15070 */
15071 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15072 {
15073 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15074 }
15075 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15076 {
15077 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15078 }
15079 else
15080 {
15081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15082 "%s:Acl Policy : %d is not supported",
15083 __func__, params->acl_policy);
15084 return -ENOTSUPP;
15085 }
15086
15087 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15088 {
15089 pConfig->num_accept_mac = params->n_acl_entries;
15090 for (i = 0; i < params->n_acl_entries; i++)
15091 {
15092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15093 "** Add ACL MAC entry %i in WhiletList :"
15094 MAC_ADDRESS_STR, i,
15095 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15096
15097 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15098 sizeof(qcmacaddr));
15099 }
15100 }
15101 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15102 {
15103 pConfig->num_deny_mac = params->n_acl_entries;
15104 for (i = 0; i < params->n_acl_entries; i++)
15105 {
15106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15107 "** Add ACL MAC entry %i in BlackList :"
15108 MAC_ADDRESS_STR, i,
15109 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15110
15111 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15112 sizeof(qcmacaddr));
15113 }
15114 }
15115
15116 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15117 {
15118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15119 "%s: SAP Set Mac Acl fail", __func__);
15120 return -EINVAL;
15121 }
15122 }
15123 else
15124 {
15125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015126 "%s: Invalid device_mode = %s (%d)",
15127 __func__, hdd_device_modetoString(pAdapter->device_mode),
15128 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015129 return -EINVAL;
15130 }
15131
15132 return 0;
15133}
15134
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015135static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15136 struct net_device *dev,
15137 const struct cfg80211_acl_data *params)
15138{
15139 int ret;
15140 vos_ssr_protect(__func__);
15141 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15142 vos_ssr_unprotect(__func__);
15143
15144 return ret;
15145}
15146
Leo Chang9056f462013-08-01 19:21:11 -070015147#ifdef WLAN_NL80211_TESTMODE
15148#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015149void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015150(
15151 void *pAdapter,
15152 void *indCont
15153)
15154{
Leo Changd9df8aa2013-09-26 13:32:26 -070015155 tSirLPHBInd *lphbInd;
15156 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015157 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015158
15159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015160 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015161
c_hpothu73f35e62014-04-18 13:40:08 +053015162 if (pAdapter == NULL)
15163 {
15164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15165 "%s: pAdapter is NULL\n",__func__);
15166 return;
15167 }
15168
Leo Chang9056f462013-08-01 19:21:11 -070015169 if (NULL == indCont)
15170 {
15171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015172 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015173 return;
15174 }
15175
c_hpothu73f35e62014-04-18 13:40:08 +053015176 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015177 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015178 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015179 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015180 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015181 GFP_ATOMIC);
15182 if (!skb)
15183 {
15184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15185 "LPHB timeout, NL buffer alloc fail");
15186 return;
15187 }
15188
Leo Changac3ba772013-10-07 09:47:04 -070015189 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015190 {
15191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15192 "WLAN_HDD_TM_ATTR_CMD put fail");
15193 goto nla_put_failure;
15194 }
Leo Changac3ba772013-10-07 09:47:04 -070015195 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015196 {
15197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15198 "WLAN_HDD_TM_ATTR_TYPE put fail");
15199 goto nla_put_failure;
15200 }
Leo Changac3ba772013-10-07 09:47:04 -070015201 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015202 sizeof(tSirLPHBInd), lphbInd))
15203 {
15204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15205 "WLAN_HDD_TM_ATTR_DATA put fail");
15206 goto nla_put_failure;
15207 }
Leo Chang9056f462013-08-01 19:21:11 -070015208 cfg80211_testmode_event(skb, GFP_ATOMIC);
15209 return;
15210
15211nla_put_failure:
15212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15213 "NLA Put fail");
15214 kfree_skb(skb);
15215
15216 return;
15217}
15218#endif /* FEATURE_WLAN_LPHB */
15219
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015220static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015221{
15222 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15223 int err = 0;
15224#ifdef FEATURE_WLAN_LPHB
15225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015226 eHalStatus smeStatus;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015227 err = wlan_hdd_validate_context(pHddCtx);
15228 if (0 != err)
15229 {
15230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15231 "%s: HDD context is not valid", __func__);
15232 return err;
15233 }
Leo Chang9056f462013-08-01 19:21:11 -070015234#endif /* FEATURE_WLAN_LPHB */
15235
15236 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15237 if (err)
15238 {
15239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15240 "%s Testmode INV ATTR", __func__);
15241 return err;
15242 }
15243
15244 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15245 {
15246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15247 "%s Testmode INV CMD", __func__);
15248 return -EINVAL;
15249 }
15250
15251 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15252 {
15253#ifdef FEATURE_WLAN_LPHB
15254 /* Low Power Heartbeat configuration request */
15255 case WLAN_HDD_TM_CMD_WLAN_HB:
15256 {
15257 int buf_len;
15258 void *buf;
15259 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015260 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015261
15262 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15263 {
15264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15265 "%s Testmode INV DATA", __func__);
15266 return -EINVAL;
15267 }
15268
15269 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15270 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015271
15272 hb_params_temp =(tSirLPHBReq *)buf;
15273 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15274 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15275 return -EINVAL;
15276
Leo Chang9056f462013-08-01 19:21:11 -070015277 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15278 if (NULL == hb_params)
15279 {
15280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15281 "%s Request Buffer Alloc Fail", __func__);
15282 return -EINVAL;
15283 }
15284
15285 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015286 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15287 hb_params,
15288 wlan_hdd_cfg80211_lphb_ind_handler);
15289 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015290 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15292 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015293 vos_mem_free(hb_params);
15294 }
Leo Chang9056f462013-08-01 19:21:11 -070015295 return 0;
15296 }
15297#endif /* FEATURE_WLAN_LPHB */
15298 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15300 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015301 return -EOPNOTSUPP;
15302 }
15303
15304 return err;
15305}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015306
15307static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15308{
15309 int ret;
15310
15311 vos_ssr_protect(__func__);
15312 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15313 vos_ssr_unprotect(__func__);
15314
15315 return ret;
15316}
Leo Chang9056f462013-08-01 19:21:11 -070015317#endif /* CONFIG_NL80211_TESTMODE */
15318
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015319static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015320 struct net_device *dev,
15321 int idx, struct survey_info *survey)
15322{
15323 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15324 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015325 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015326 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015327 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015328 v_S7_t snr,rssi;
15329 int status, i, j, filled = 0;
15330
15331 ENTER();
15332
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015333 if (NULL == pAdapter)
15334 {
15335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15336 "%s: HDD adapter is Null", __func__);
15337 return -ENODEV;
15338 }
15339
15340 if (NULL == wiphy)
15341 {
15342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15343 "%s: wiphy is Null", __func__);
15344 return -ENODEV;
15345 }
15346
15347 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15348 status = wlan_hdd_validate_context(pHddCtx);
15349
15350 if (0 != status)
15351 {
15352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15353 "%s: HDD context is not valid", __func__);
15354 return status;
15355 }
15356
Mihir Sheted9072e02013-08-21 17:02:29 +053015357 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15358
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015359 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015360 0 != pAdapter->survey_idx ||
15361 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015362 {
15363 /* The survey dump ops when implemented completely is expected to
15364 * return a survey of all channels and the ops is called by the
15365 * kernel with incremental values of the argument 'idx' till it
15366 * returns -ENONET. But we can only support the survey for the
15367 * operating channel for now. survey_idx is used to track
15368 * that the ops is called only once and then return -ENONET for
15369 * the next iteration
15370 */
15371 pAdapter->survey_idx = 0;
15372 return -ENONET;
15373 }
15374
15375 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15376
15377 wlan_hdd_get_snr(pAdapter, &snr);
15378 wlan_hdd_get_rssi(pAdapter, &rssi);
15379
15380 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15381 hdd_wlan_get_freq(channel, &freq);
15382
15383
15384 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15385 {
15386 if (NULL == wiphy->bands[i])
15387 {
15388 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15389 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15390 continue;
15391 }
15392
15393 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15394 {
15395 struct ieee80211_supported_band *band = wiphy->bands[i];
15396
15397 if (band->channels[j].center_freq == (v_U16_t)freq)
15398 {
15399 survey->channel = &band->channels[j];
15400 /* The Rx BDs contain SNR values in dB for the received frames
15401 * while the supplicant expects noise. So we calculate and
15402 * return the value of noise (dBm)
15403 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15404 */
15405 survey->noise = rssi - snr;
15406 survey->filled = SURVEY_INFO_NOISE_DBM;
15407 filled = 1;
15408 }
15409 }
15410 }
15411
15412 if (filled)
15413 pAdapter->survey_idx = 1;
15414 else
15415 {
15416 pAdapter->survey_idx = 0;
15417 return -ENONET;
15418 }
15419
15420 return 0;
15421}
15422
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015423static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15424 struct net_device *dev,
15425 int idx, struct survey_info *survey)
15426{
15427 int ret;
15428
15429 vos_ssr_protect(__func__);
15430 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15431 vos_ssr_unprotect(__func__);
15432
15433 return ret;
15434}
15435
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015436/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015437 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015438 * this is called when cfg80211 driver resume
15439 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15440 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015441int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015442{
15443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15444 hdd_adapter_t *pAdapter;
15445 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15446 VOS_STATUS status = VOS_STATUS_SUCCESS;
15447
15448 ENTER();
15449
15450 if ( NULL == pHddCtx )
15451 {
15452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15453 "%s: HddCtx validation failed", __func__);
15454 return 0;
15455 }
15456
15457 if (pHddCtx->isLogpInProgress)
15458 {
15459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15460 "%s: LOGP in Progress. Ignore!!!", __func__);
15461 return 0;
15462 }
15463
Mihir Shete18156292014-03-11 15:38:30 +053015464 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015465 {
15466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15467 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15468 return 0;
15469 }
15470
15471 spin_lock(&pHddCtx->schedScan_lock);
15472 pHddCtx->isWiphySuspended = FALSE;
15473 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15474 {
15475 spin_unlock(&pHddCtx->schedScan_lock);
15476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15477 "%s: Return resume is not due to PNO indication", __func__);
15478 return 0;
15479 }
15480 // Reset flag to avoid updatating cfg80211 data old results again
15481 pHddCtx->isSchedScanUpdatePending = FALSE;
15482 spin_unlock(&pHddCtx->schedScan_lock);
15483
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015484
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015485 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15486
15487 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15488 {
15489 pAdapter = pAdapterNode->pAdapter;
15490 if ( (NULL != pAdapter) &&
15491 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15492 {
15493 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015494 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15496 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015497 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015498 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015499 {
15500 /* Acquire wakelock to handle the case where APP's tries to
15501 * suspend immediately after updating the scan results. Whis
15502 * results in app's is in suspended state and not able to
15503 * process the connect request to AP
15504 */
15505 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015506 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015507 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015508
15509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15510 "%s : cfg80211 scan result database updated", __func__);
15511
15512 return 0;
15513
15514 }
15515 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15516 pAdapterNode = pNext;
15517 }
15518
15519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15520 "%s: Failed to find Adapter", __func__);
15521 return 0;
15522}
15523
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015524int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15525{
15526 int ret;
15527
15528 vos_ssr_protect(__func__);
15529 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15530 vos_ssr_unprotect(__func__);
15531
15532 return ret;
15533}
15534
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015535/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015536 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015537 * this is called when cfg80211 driver suspends
15538 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015539int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015540 struct cfg80211_wowlan *wow)
15541{
15542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015543 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015544
15545 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015546 ret = wlan_hdd_validate_context(pHddCtx);
15547 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015548 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15550 "%s: HDD context is not valid", __func__);
15551 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015552 }
15553
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015554
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015555 pHddCtx->isWiphySuspended = TRUE;
15556
15557 EXIT();
15558
15559 return 0;
15560}
15561
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015562int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15563 struct cfg80211_wowlan *wow)
15564{
15565 int ret;
15566
15567 vos_ssr_protect(__func__);
15568 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15569 vos_ssr_unprotect(__func__);
15570
15571 return ret;
15572}
Jeff Johnson295189b2012-06-20 16:38:30 -070015573/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015574static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015575{
15576 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15577 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15578 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15579 .change_station = wlan_hdd_change_station,
15580#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15581 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15582 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15583 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015584#else
15585 .start_ap = wlan_hdd_cfg80211_start_ap,
15586 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15587 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015588#endif
15589 .change_bss = wlan_hdd_cfg80211_change_bss,
15590 .add_key = wlan_hdd_cfg80211_add_key,
15591 .get_key = wlan_hdd_cfg80211_get_key,
15592 .del_key = wlan_hdd_cfg80211_del_key,
15593 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015594#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015595 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015596#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015597 .scan = wlan_hdd_cfg80211_scan,
15598 .connect = wlan_hdd_cfg80211_connect,
15599 .disconnect = wlan_hdd_cfg80211_disconnect,
15600 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15601 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15602 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15603 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15604 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015605 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15606 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015607 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15609 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15610 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15611 .set_txq_params = wlan_hdd_set_txq_params,
15612#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 .get_station = wlan_hdd_cfg80211_get_station,
15614 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15615 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015616 .add_station = wlan_hdd_cfg80211_add_station,
15617#ifdef FEATURE_WLAN_LFR
15618 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15619 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15620 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15621#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015622#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15623 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15624#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015625#ifdef FEATURE_WLAN_TDLS
15626 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15627 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15628#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015629#ifdef WLAN_FEATURE_GTK_OFFLOAD
15630 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15631#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015632#ifdef FEATURE_WLAN_SCAN_PNO
15633 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15634 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15635#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015636 .resume = wlan_hdd_cfg80211_resume_wlan,
15637 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015638 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015639#ifdef WLAN_NL80211_TESTMODE
15640 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15641#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015642 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015643};
15644