blob: 5a121bab1ac25902ff4769ff04f563463e8b6d12 [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);
Mohit Khanna0f232092012-09-11 14:46:08 -07007538 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
7539 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.
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 hdd_deinit_adapter( pHddCtx, pAdapter );
7562 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
Jeff Johnson32d95a32012-09-10 13:15:23 -07007680 hdd_deinit_adapter( pHddCtx, pAdapter );
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) &&
9832 smeNeighborRoamIsHandoffInProgress(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9833 {
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,
10170 "Return old cached scan as all channels"
10171 "and no of channles are same");
10172 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);
10176 return eHAL_STATUS_SUCCESS ;
10177 }
10178 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010179 }
10180
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010181 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10182 * search (Flush on both full scan and social scan but not on single
10183 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10184 */
10185
10186 /* Supplicant does single channel scan after 8-way handshake
10187 * and in that case driver shoudnt flush scan results. If
10188 * driver flushes the scan results here and unfortunately if
10189 * the AP doesnt respond to our probe req then association
10190 * fails which is not desired
10191 */
10192
10193 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
10194 {
10195 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10196 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10197 pAdapter->sessionId );
10198 }
10199
10200 if( request->ie_len )
10201 {
10202 /* save this for future association (join requires this) */
10203 /*TODO: Array needs to be converted to dynamic allocation,
10204 * as multiple ie.s can be sent in cfg80211_scan_request structure
10205 * CR 597966
10206 */
10207 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10208 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
10209 pScanInfo->scanAddIE.length = request->ie_len;
10210
10211 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10212 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10213 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010215 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010217 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
10218 memcpy( pwextBuf->roamProfile.addIEScan,
10219 request->ie, request->ie_len);
10220 }
10221 else
10222 {
10223 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
10224 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 }
10226
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010227 }
10228 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
10229 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
10230
10231 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
10232 request->ie_len);
10233 if (pP2pIe != NULL)
10234 {
10235#ifdef WLAN_FEATURE_P2P_DEBUG
10236 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
10237 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
10238 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053010239 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010240 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
10241 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10242 "Go nego completed to Connection is started");
10243 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10244 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053010245 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010246 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
10247 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010249 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
10250 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
10251 "Disconnected state to Connection is started");
10252 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
10253 "for 4way Handshake");
10254 }
10255#endif
10256
10257 /* no_cck will be set during p2p find to disable 11b rates */
10258 if(TRUE == request->no_cck)
10259 {
10260 hddLog(VOS_TRACE_LEVEL_INFO,
10261 "%s: This is a P2P Search", __func__);
10262 scanRequest.p2pSearch = 1;
10263
10264 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053010265 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010266 /* set requestType to P2P Discovery */
10267 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
10268 }
10269
10270 /*
10271 Skip Dfs Channel in case of P2P Search
10272 if it is set in ini file
10273 */
10274 if(cfg_param->skipDfsChnlInP2pSearch)
10275 {
10276 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010277 }
10278 else
10279 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010280 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053010281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010282
Agarwal Ashish4f616132013-12-30 23:32:50 +053010283 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 }
10285 }
10286
10287 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
10288
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010289 /* acquire the wakelock to avoid the apps suspend during the scan. To
10290 * address the following issues.
10291 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
10292 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
10293 * for long time, this result in apps running at full power for long time.
10294 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
10295 * be stuck in full power because of resume BMPS
10296 */
10297 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -070010298
Nirav Shah20ac06f2013-12-12 18:14:06 +053010299 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10300 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010301 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
10302 scanRequest.requestType, scanRequest.scanType,
10303 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053010304 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
10305
Siddharth Bhal76972212014-10-15 16:22:51 +053010306 if (pHddCtx->spoofMacAddr.isEnabled)
10307 {
10308 hddLog(VOS_TRACE_LEVEL_INFO,
10309 "%s: MAC Spoofing enabled for current scan", __func__);
10310 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
10311 * to fill TxBds for probe request during current scan
10312 */
10313 WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
10314 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
10315 }
10316
Jeff Johnsone7245742012-09-05 17:12:55 -070010317 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 pAdapter->sessionId, &scanRequest, &scanId,
10319 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070010320
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 if (eHAL_STATUS_SUCCESS != status)
10322 {
10323 hddLog(VOS_TRACE_LEVEL_ERROR,
10324 "%s: sme_ScanRequest returned error %d", __func__, status);
10325 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010326 if(eHAL_STATUS_RESOURCES == status)
10327 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
10329 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070010330 status = -EBUSY;
10331 } else {
10332 status = -EIO;
10333 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010334 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 goto free_mem;
10336 }
10337
10338 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010339 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 pAdapter->request = request;
10341 pScanInfo->scanId = scanId;
10342
10343 complete(&pScanInfo->scan_req_completion_event);
10344
10345free_mem:
10346 if( scanRequest.SSIDs.SSIDList )
10347 {
10348 vos_mem_free(scanRequest.SSIDs.SSIDList);
10349 }
10350
10351 if( channelList )
10352 vos_mem_free( channelList );
10353
10354 EXIT();
10355
10356 return status;
10357}
10358
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010359int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
10360#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10361 struct net_device *dev,
10362#endif
10363 struct cfg80211_scan_request *request)
10364{
10365 int ret;
10366
10367 vos_ssr_protect(__func__);
10368 ret = __wlan_hdd_cfg80211_scan(wiphy,
10369#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10370 dev,
10371#endif
10372 request);
10373 vos_ssr_unprotect(__func__);
10374
10375 return ret;
10376}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010377
10378void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
10379{
10380 v_U8_t iniDot11Mode =
10381 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
10382 eHddDot11Mode hddDot11Mode = iniDot11Mode;
10383
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010384 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
10385 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010386 switch ( iniDot11Mode )
10387 {
10388 case eHDD_DOT11_MODE_AUTO:
10389 case eHDD_DOT11_MODE_11ac:
10390 case eHDD_DOT11_MODE_11ac_ONLY:
10391#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053010392 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
10393 sme_IsFeatureSupportedByFW(DOT11AC) )
10394 hddDot11Mode = eHDD_DOT11_MODE_11ac;
10395 else
10396 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010397#else
10398 hddDot11Mode = eHDD_DOT11_MODE_11n;
10399#endif
10400 break;
10401 case eHDD_DOT11_MODE_11n:
10402 case eHDD_DOT11_MODE_11n_ONLY:
10403 hddDot11Mode = eHDD_DOT11_MODE_11n;
10404 break;
10405 default:
10406 hddDot11Mode = iniDot11Mode;
10407 break;
10408 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010409#ifdef WLAN_FEATURE_AP_HT40_24G
10410 if (operationChannel > SIR_11B_CHANNEL_END)
10411#endif
10412 {
10413 /* This call decides required channel bonding mode */
10414 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010415 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
10416 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010417 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010418}
10419
Jeff Johnson295189b2012-06-20 16:38:30 -070010420/*
10421 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010422 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010425 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010426{
10427 int status = 0;
10428 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080010429 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 v_U32_t roamId;
10431 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 eCsrAuthType RSNAuthType;
10433
10434 ENTER();
10435
10436 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080010437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10438
10439 status = wlan_hdd_validate_context(pHddCtx);
10440 if (status)
10441 {
10442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10443 "%s: HDD context is not valid!", __func__);
10444 return status;
10445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
10448 {
10449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
10450 return -EINVAL;
10451 }
10452
10453 pRoamProfile = &pWextState->roamProfile;
10454
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 {
Jeff Johnsone7245742012-09-05 17:12:55 -070010457 hdd_station_ctx_t *pHddStaCtx;
10458 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010459
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010460 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
10462 {
10463 /*QoS not enabled in cfg file*/
10464 pRoamProfile->uapsd_mask = 0;
10465 }
10466 else
10467 {
10468 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010469 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
10471 }
10472
10473 pRoamProfile->SSIDs.numOfSSIDs = 1;
10474 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
10475 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010476 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
10478 ssid, ssid_len);
10479
10480 if (bssid)
10481 {
10482 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
10483 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
10484 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010485 /* Save BSSID in seperate variable as well, as RoamProfile
10486 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 case of join failure we should send valid BSSID to supplicant
10488 */
10489 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
10490 WNI_CFG_BSSID_LEN);
10491 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070010492 else
10493 {
10494 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
10495 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010496
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010497 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
10498 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
10500 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010501 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 /*set gen ie*/
10503 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
10504 /*set auth*/
10505 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
10506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010507#ifdef FEATURE_WLAN_WAPI
10508 if (pAdapter->wapi_info.nWapiMode)
10509 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010510 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 switch (pAdapter->wapi_info.wapiAuthMode)
10512 {
10513 case WAPI_AUTH_MODE_PSK:
10514 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010515 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 pAdapter->wapi_info.wapiAuthMode);
10517 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
10518 break;
10519 }
10520 case WAPI_AUTH_MODE_CERT:
10521 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010522 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 pAdapter->wapi_info.wapiAuthMode);
10524 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
10525 break;
10526 }
10527 } // End of switch
10528 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
10529 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
10530 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010531 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010532 pRoamProfile->AuthType.numEntries = 1;
10533 pRoamProfile->EncryptionType.numEntries = 1;
10534 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10535 pRoamProfile->mcEncryptionType.numEntries = 1;
10536 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
10537 }
10538 }
10539#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010540#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010541 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010542 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10543 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
10544 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053010545 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
10546 sizeof (tSirGtkOffloadParams));
10547 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010548 }
10549#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 pRoamProfile->csrPersona = pAdapter->device_mode;
10551
Jeff Johnson32d95a32012-09-10 13:15:23 -070010552 if( operatingChannel )
10553 {
10554 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
10555 pRoamProfile->ChannelInfo.numOfChannels = 1;
10556 }
Chet Lanctot186b5732013-03-18 10:26:30 -070010557 else
10558 {
10559 pRoamProfile->ChannelInfo.ChannelList = NULL;
10560 pRoamProfile->ChannelInfo.numOfChannels = 0;
10561 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010562 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
10563 {
10564 hdd_select_cbmode(pAdapter,operatingChannel);
10565 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010566
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010567 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
10568 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010569 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010570 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010571 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
10572 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010573 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10574 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053010575 {
10576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10577 "%s: Set HDD connState to eConnectionState_Connecting",
10578 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010579 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
10580 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053010581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010582 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 pAdapter->sessionId, pRoamProfile, &roamId);
10584
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010585 if ((eHAL_STATUS_SUCCESS != status) &&
10586 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10587 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010588
10589 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010590 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
10591 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
10592 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010593 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080010594 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053010595 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080010596
10597 pRoamProfile->ChannelInfo.ChannelList = NULL;
10598 pRoamProfile->ChannelInfo.numOfChannels = 0;
10599
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 }
10601 else
10602 {
10603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
10604 return -EINVAL;
10605 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010606 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 return status;
10608}
10609
10610/*
10611 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
10612 * This function is used to set the authentication type (OPEN/SHARED).
10613 *
10614 */
10615static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
10616 enum nl80211_auth_type auth_type)
10617{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010618 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10620
10621 ENTER();
10622
10623 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010624 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070010625 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010626 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010627 hddLog(VOS_TRACE_LEVEL_INFO,
10628 "%s: set authentication type to AUTOSWITCH", __func__);
10629 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
10630 break;
10631
10632 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010633#ifdef WLAN_FEATURE_VOWIFI_11R
10634 case NL80211_AUTHTYPE_FT:
10635#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010636 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010637 "%s: set authentication type to OPEN", __func__);
10638 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10639 break;
10640
10641 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010642 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 "%s: set authentication type to SHARED", __func__);
10644 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
10645 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010646#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010648 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070010649 "%s: set authentication type to CCKM WPA", __func__);
10650 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
10651 break;
10652#endif
10653
10654
10655 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010656 hddLog(VOS_TRACE_LEVEL_ERROR,
10657 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010658 auth_type);
10659 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
10660 return -EINVAL;
10661 }
10662
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010663 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 pHddStaCtx->conn_info.authType;
10665 return 0;
10666}
10667
10668/*
10669 * FUNCTION: wlan_hdd_set_akm_suite
10670 * This function is used to set the key mgmt type(PSK/8021x).
10671 *
10672 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 u32 key_mgmt
10675 )
10676{
10677 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10678 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053010679 /* Should be in ieee802_11_defs.h */
10680#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
10681#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 /*set key mgmt type*/
10683 switch(key_mgmt)
10684 {
10685 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053010686 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010687#ifdef WLAN_FEATURE_VOWIFI_11R
10688 case WLAN_AKM_SUITE_FT_PSK:
10689#endif
10690 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070010691 __func__);
10692 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
10693 break;
10694
10695 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053010696 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053010697#ifdef WLAN_FEATURE_VOWIFI_11R
10698 case WLAN_AKM_SUITE_FT_8021X:
10699#endif
10700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 __func__);
10702 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10703 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010704#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010705#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
10706#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
10707 case WLAN_AKM_SUITE_CCKM:
10708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
10709 __func__);
10710 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
10711 break;
10712#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070010713#ifndef WLAN_AKM_SUITE_OSEN
10714#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
10715 case WLAN_AKM_SUITE_OSEN:
10716 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
10717 __func__);
10718 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
10719 break;
10720#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010721
10722 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 __func__, key_mgmt);
10725 return -EINVAL;
10726
10727 }
10728 return 0;
10729}
10730
10731/*
10732 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010733 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 * (NONE/WEP40/WEP104/TKIP/CCMP).
10735 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010736static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
10737 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070010738 bool ucast
10739 )
10740{
10741 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010742 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010743 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10744
10745 ENTER();
10746
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010747 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070010750 __func__, cipher);
10751 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10752 }
10753 else
10754 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010755
Jeff Johnson295189b2012-06-20 16:38:30 -070010756 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010757 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010758 {
10759 case IW_AUTH_CIPHER_NONE:
10760 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10761 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010762
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010764 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010766
Jeff Johnson295189b2012-06-20 16:38:30 -070010767 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053010768 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010770
Jeff Johnson295189b2012-06-20 16:38:30 -070010771 case WLAN_CIPHER_SUITE_TKIP:
10772 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
10773 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010774
Jeff Johnson295189b2012-06-20 16:38:30 -070010775 case WLAN_CIPHER_SUITE_CCMP:
10776 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10777 break;
10778#ifdef FEATURE_WLAN_WAPI
10779 case WLAN_CIPHER_SUITE_SMS4:
10780 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
10781 break;
10782#endif
10783
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010784#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 case WLAN_CIPHER_SUITE_KRK:
10786 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
10787 break;
10788#endif
10789 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 __func__, cipher);
10792 return -EOPNOTSUPP;
10793 }
10794 }
10795
10796 if (ucast)
10797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 __func__, encryptionType);
10800 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10801 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010802 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 encryptionType;
10804 }
10805 else
10806 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010807 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 __func__, encryptionType);
10809 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
10810 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
10811 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
10812 }
10813
10814 return 0;
10815}
10816
10817
10818/*
10819 * FUNCTION: wlan_hdd_cfg80211_set_ie
10820 * This function is used to parse WPA/RSN IE's.
10821 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010822int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
10823 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 size_t ie_len
10825 )
10826{
10827 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10828 u8 *genie = ie;
10829 v_U16_t remLen = ie_len;
10830#ifdef FEATURE_WLAN_WAPI
10831 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
10832 u16 *tmp;
10833 v_U16_t akmsuiteCount;
10834 int *akmlist;
10835#endif
10836 ENTER();
10837
10838 /* clear previous assocAddIE */
10839 pWextState->assocAddIE.length = 0;
10840 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010841 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010842
10843 while (remLen >= 2)
10844 {
10845 v_U16_t eLen = 0;
10846 v_U8_t elementId;
10847 elementId = *genie++;
10848 eLen = *genie++;
10849 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010850
Arif Hussain6d2a3322013-11-17 19:50:10 -080010851 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010853
10854 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010856 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010857 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 -070010858 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010859 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010860 "%s: Invalid WPA IE", __func__);
10861 return -EINVAL;
10862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 {
10865 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010866 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10870 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010871 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
10872 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 VOS_ASSERT(0);
10874 return -ENOMEM;
10875 }
10876 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10877 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10878 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010879
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
10881 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10882 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10883 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
10885 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
10887 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
10888 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
10889 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
10890 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
10891 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010892 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053010893 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 {
10895 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010898
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10900 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010901 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10902 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 VOS_ASSERT(0);
10904 return -ENOMEM;
10905 }
10906 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
10907 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10908 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010909
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10911 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010913#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010914 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
10915 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 /*Consider WFD IE, only for P2P Client */
10917 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10918 {
10919 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010920 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070010921 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010922
Jeff Johnson295189b2012-06-20 16:38:30 -070010923 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10924 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010925 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10926 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 VOS_ASSERT(0);
10928 return -ENOMEM;
10929 }
10930 // WFD IE is saved to Additional IE ; it should be accumulated to handle
10931 // WPS IE + P2P IE + WFD IE
10932 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10933 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010934
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10936 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10937 }
10938#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010939 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010941 HS20_OUI_TYPE_SIZE)) )
10942 {
10943 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010945 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010946
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010947 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10948 {
Jeff Johnson902c9832012-12-10 14:28:09 -080010949 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10950 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010951 VOS_ASSERT(0);
10952 return -ENOMEM;
10953 }
10954 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10955 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010956
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070010957 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10958 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10959 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010960 /* Appending OSEN Information Element in Assiciation Request */
10961 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
10962 OSEN_OUI_TYPE_SIZE)) )
10963 {
10964 v_U16_t curAddIELen = pWextState->assocAddIE.length;
10965 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
10966 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070010967
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070010968 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
10969 {
10970 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
10971 "Need bigger buffer space");
10972 VOS_ASSERT(0);
10973 return -ENOMEM;
10974 }
10975 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
10976 pWextState->assocAddIE.length += eLen + 2;
10977
10978 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
10979 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
10980 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
10981 }
10982
10983 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070010984 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
10985
10986 /* populating as ADDIE in beacon frames */
10987 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
10988 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
10989 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
10990 {
10991 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
10992 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10993 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10994 {
10995 hddLog(LOGE,
10996 "Coldn't pass "
10997 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
10998 }
10999 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11000 else
11001 hddLog(LOGE,
11002 "Could not pass on "
11003 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11004
11005 /* IBSS mode doesn't contain params->proberesp_ies still
11006 beaconIE's need to be populated in probe response frames */
11007 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11008 {
11009 u16 rem_probe_resp_ie_len = eLen + 2;
11010 u8 probe_rsp_ie_len[3] = {0};
11011 u8 counter = 0;
11012
11013 /* Check Probe Resp Length if it is greater then 255 then
11014 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11015 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11016 not able Store More then 255 bytes into One Variable */
11017
11018 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11019 {
11020 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11021 {
11022 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11023 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11024 }
11025 else
11026 {
11027 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11028 rem_probe_resp_ie_len = 0;
11029 }
11030 }
11031
11032 rem_probe_resp_ie_len = 0;
11033
11034 if (probe_rsp_ie_len[0] > 0)
11035 {
11036 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11037 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11038 (tANI_U8*)(genie - 2),
11039 probe_rsp_ie_len[0], NULL,
11040 eANI_BOOLEAN_FALSE)
11041 == eHAL_STATUS_FAILURE)
11042 {
11043 hddLog(LOGE,
11044 "Could not pass"
11045 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11046 }
11047 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11048 }
11049
11050 if (probe_rsp_ie_len[1] > 0)
11051 {
11052 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11053 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11054 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11055 probe_rsp_ie_len[1], NULL,
11056 eANI_BOOLEAN_FALSE)
11057 == eHAL_STATUS_FAILURE)
11058 {
11059 hddLog(LOGE,
11060 "Could not pass"
11061 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11062 }
11063 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11064 }
11065
11066 if (probe_rsp_ie_len[2] > 0)
11067 {
11068 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11069 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11070 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11071 probe_rsp_ie_len[2], NULL,
11072 eANI_BOOLEAN_FALSE)
11073 == eHAL_STATUS_FAILURE)
11074 {
11075 hddLog(LOGE,
11076 "Could not pass"
11077 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11078 }
11079 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11080 }
11081
11082 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11083 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11084 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11085 {
11086 hddLog(LOGE,
11087 "Could not pass"
11088 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11089 }
11090 }
11091 else
11092 {
11093 // Reset WNI_CFG_PROBE_RSP Flags
11094 wlan_hdd_reset_prob_rspies(pAdapter);
11095
11096 hddLog(VOS_TRACE_LEVEL_INFO,
11097 "%s: No Probe Response IE received in set beacon",
11098 __func__);
11099 }
11100 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011101 break;
11102 case DOT11F_EID_RSN:
11103 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11104 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11105 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11106 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11107 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11108 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011109 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
11110 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011112 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011113 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011114 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011115
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011116 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
11117 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011118 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11119 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011120 VOS_ASSERT(0);
11121 return -ENOMEM;
11122 }
11123 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11124 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011125
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011126 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11127 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11128 break;
11129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011130#ifdef FEATURE_WLAN_WAPI
11131 case WLAN_EID_WAPI:
11132 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011133 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 pAdapter->wapi_info.nWapiMode);
11135 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011136 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011137 akmsuiteCount = WPA_GET_LE16(tmp);
11138 tmp = tmp + 1;
11139 akmlist = (int *)(tmp);
11140 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11141 {
11142 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11143 }
11144 else
11145 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011146 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 VOS_ASSERT(0);
11148 return -EINVAL;
11149 }
11150
11151 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11152 {
11153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011154 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011156 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011160 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
11162 }
11163 break;
11164#endif
11165 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011168 /* when Unknown IE is received we should break and continue
11169 * to the next IE in the buffer instead we were returning
11170 * so changing this to break */
11171 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 }
11173 genie += eLen;
11174 remLen -= eLen;
11175 }
11176 EXIT();
11177 return 0;
11178}
11179
11180/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053011181 * FUNCTION: hdd_isWPAIEPresent
11182 * Parse the received IE to find the WPA IE
11183 *
11184 */
11185static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
11186{
11187 v_U8_t eLen = 0;
11188 v_U16_t remLen = ie_len;
11189 v_U8_t elementId = 0;
11190
11191 while (remLen >= 2)
11192 {
11193 elementId = *ie++;
11194 eLen = *ie++;
11195 remLen -= 2;
11196 if (eLen > remLen)
11197 {
11198 hddLog(VOS_TRACE_LEVEL_ERROR,
11199 "%s: IE length is wrong %d", __func__, eLen);
11200 return FALSE;
11201 }
11202 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
11203 {
11204 /* OUI - 0x00 0X50 0XF2
11205 WPA Information Element - 0x01
11206 WPA version - 0x01*/
11207 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
11208 return TRUE;
11209 }
11210 ie += eLen;
11211 remLen -= eLen;
11212 }
11213 return FALSE;
11214}
11215
11216/*
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011218 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 * parameters during connect operation.
11220 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 struct cfg80211_connect_params *req
11223 )
11224{
11225 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011226 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 ENTER();
11228
11229 /*set wpa version*/
11230 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11231
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011232 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011233 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053011234 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
11236 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11237 }
11238 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
11239 {
11240 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11241 }
11242 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243
11244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011245 pWextState->wpaVersion);
11246
11247 /*set authentication type*/
11248 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
11249
11250 if (0 > status)
11251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011252 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 "%s: failed to set authentication type ", __func__);
11254 return status;
11255 }
11256
11257 /*set key mgmt type*/
11258 if (req->crypto.n_akm_suites)
11259 {
11260 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
11261 if (0 > status)
11262 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 __func__);
11265 return status;
11266 }
11267 }
11268
11269 /*set pairwise cipher type*/
11270 if (req->crypto.n_ciphers_pairwise)
11271 {
11272 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
11273 req->crypto.ciphers_pairwise[0], true);
11274 if (0 > status)
11275 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011276 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 "%s: failed to set unicast cipher type", __func__);
11278 return status;
11279 }
11280 }
11281 else
11282 {
11283 /*Reset previous cipher suite to none*/
11284 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
11285 if (0 > status)
11286 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011287 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 "%s: failed to set unicast cipher type", __func__);
11289 return status;
11290 }
11291 }
11292
11293 /*set group cipher type*/
11294 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
11295 false);
11296
11297 if (0 > status)
11298 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011299 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 __func__);
11301 return status;
11302 }
11303
Chet Lanctot186b5732013-03-18 10:26:30 -070011304#ifdef WLAN_FEATURE_11W
11305 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
11306#endif
11307
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
11309 if (req->ie_len)
11310 {
11311 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
11312 if ( 0 > status)
11313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 __func__);
11316 return status;
11317 }
11318 }
11319
11320 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011321 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 {
11323 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
11324 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
11325 )
11326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011327 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
11329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 __func__);
11332 return -EOPNOTSUPP;
11333 }
11334 else
11335 {
11336 u8 key_len = req->key_len;
11337 u8 key_idx = req->key_idx;
11338
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011339 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 && (CSR_MAX_NUM_KEY > key_idx)
11341 )
11342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011343 hddLog(VOS_TRACE_LEVEL_INFO,
11344 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 __func__, key_idx, key_len);
11346 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011349 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 (u8)key_len;
11351 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
11352 }
11353 }
11354 }
11355 }
11356
11357 return status;
11358}
11359
11360/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011361 * FUNCTION: wlan_hdd_try_disconnect
11362 * This function is used to disconnect from previous
11363 * connection
11364 */
11365static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
11366{
11367 long ret = 0;
11368 hdd_station_ctx_t *pHddStaCtx;
11369 eMib_dot11DesiredBssType connectedBssType;
11370
11371 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11372
11373 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
11374
11375 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
11376 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
11377 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
11378 {
11379 /* Issue disconnect to CSR */
11380 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11381 if( eHAL_STATUS_SUCCESS ==
11382 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11383 pAdapter->sessionId,
11384 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11385 {
11386 ret = wait_for_completion_interruptible_timeout(
11387 &pAdapter->disconnect_comp_var,
11388 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11389 if (0 >= ret)
11390 {
11391 hddLog(LOGE, FL("Failed to receive disconnect event"));
11392 return -EALREADY;
11393 }
11394 }
11395 }
11396 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
11397 {
11398 ret = wait_for_completion_interruptible_timeout(
11399 &pAdapter->disconnect_comp_var,
11400 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
11401 if (0 >= ret)
11402 {
11403 hddLog(LOGE, FL("Failed to receive disconnect event"));
11404 return -EALREADY;
11405 }
11406 }
11407
11408 return 0;
11409}
11410
11411/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053011412 * FUNCTION: __wlan_hdd_cfg80211_connect
11413 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011415static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 struct net_device *ndev,
11417 struct cfg80211_connect_params *req
11418 )
11419{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011420 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011421 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053011423 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011424
11425 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011426
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11428 TRACE_CODE_HDD_CFG80211_CONNECT,
11429 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011430 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011431 "%s: device_mode = %s (%d)", __func__,
11432 hdd_device_modetoString(pAdapter->device_mode),
11433 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011434
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011436 if (!pHddCtx)
11437 {
11438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11439 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011440 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011441 }
11442
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011443 status = wlan_hdd_validate_context(pHddCtx);
11444
11445 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11448 "%s: HDD context is not valid", __func__);
11449 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011450 }
11451
Agarwal Ashish51325b52014-06-16 16:50:49 +053011452 if (vos_max_concurrent_connections_reached()) {
11453 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11454 return -ECONNREFUSED;
11455 }
11456
Jeff Johnson295189b2012-06-20 16:38:30 -070011457#ifdef WLAN_BTAMP_FEATURE
11458 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011459 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011463 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 }
11465#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011466
11467 //If Device Mode is Station Concurrent Sessions Exit BMps
11468 //P2P Mode will be taken care in Open/close adapter
11469 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053011470 (vos_concurrent_open_sessions_running())) {
11471 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
11472 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011473 }
11474
11475 /*Try disconnecting if already in connected state*/
11476 status = wlan_hdd_try_disconnect(pAdapter);
11477 if ( 0 > status)
11478 {
11479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11480 " connection"));
11481 return -EALREADY;
11482 }
11483
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070011486
11487 if ( 0 > status)
11488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011489 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 __func__);
11491 return status;
11492 }
Mohit Khanna765234a2012-09-11 15:08:35 -070011493 if ( req->channel )
11494 {
11495 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
11496 req->ssid_len, req->bssid,
11497 req->channel->hw_value);
11498 }
11499 else
11500 {
11501 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011502 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070011503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011504
11505 if (0 > status)
11506 {
11507 //ReEnable BMPS if disabled
11508 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
11509 (NULL != pHddCtx))
11510 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011511 if (pHddCtx->hdd_wlan_suspended)
11512 {
11513 hdd_set_pwrparams(pHddCtx);
11514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 //ReEnable Bmps and Imps back
11516 hdd_enable_bmps_imps(pHddCtx);
11517 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 return status;
11520 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011521 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011522 EXIT();
11523 return status;
11524}
11525
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011526static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
11527 struct net_device *ndev,
11528 struct cfg80211_connect_params *req)
11529{
11530 int ret;
11531 vos_ssr_protect(__func__);
11532 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
11533 vos_ssr_unprotect(__func__);
11534
11535 return ret;
11536}
Jeff Johnson295189b2012-06-20 16:38:30 -070011537
11538/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011539 * FUNCTION: wlan_hdd_disconnect
11540 * This function is used to issue a disconnect request to SME
11541 */
11542int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
11543{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011544 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011546 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011547 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548
11549 status = wlan_hdd_validate_context(pHddCtx);
11550
11551 if (0 != status)
11552 {
11553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11554 "%s: HDD context is not valid", __func__);
11555 return status;
11556 }
11557
11558 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011559
Agarwal Ashish47d18112014-08-04 19:55:07 +053011560 /* Need to apply spin lock before decreasing active sessions
11561 * as there can be chance for double decrement if context switch
11562 * Calls hdd_DisConnectHandler.
11563 */
11564
11565 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011566 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11567 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011568 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11569 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053011570 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
11571 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053011572
Abhishek Singhf4669da2014-05-26 15:07:49 +053011573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053011574 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
11575
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011576 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011577
Mihir Shete182a0b22014-08-18 16:08:48 +053011578 /*
11579 * stop tx queues before deleting STA/BSS context from the firmware.
11580 * tx has to be disabled because the firmware can get busy dropping
11581 * the tx frames after BSS/STA has been deleted and will not send
11582 * back a response resulting in WDI timeout
11583 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011584 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053011585 netif_tx_disable(pAdapter->dev);
11586 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011587
Mihir Shete182a0b22014-08-18 16:08:48 +053011588 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011589 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11590 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011591 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
11592 {
11593 hddLog(VOS_TRACE_LEVEL_INFO,
11594 FL("status = %d, already disconnected"),
11595 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011596
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011597 }
11598 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011599 {
11600 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011601 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011602 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011603 result = -EINVAL;
11604 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011605 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011606 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011607 &pAdapter->disconnect_comp_var,
11608 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011609 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011610 {
11611 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011612 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011613 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011614 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011615 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011616 {
11617 hddLog(VOS_TRACE_LEVEL_ERROR,
11618 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011619 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011620 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011621disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053011622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11623 FL("Set HDD connState to eConnectionState_NotConnected"));
11624 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
11625
Abhishek Singh6ab864d2014-11-27 12:10:10 +053011626 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011627}
11628
11629
11630/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011631 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 * This function is used to issue a disconnect request to SME
11633 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011634static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 struct net_device *dev,
11636 u16 reason
11637 )
11638{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011640 tCsrRoamProfile *pRoamProfile =
11641 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011643 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11644 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011645#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011646 tANI_U8 staIdx;
11647#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011648
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11652 TRACE_CODE_HDD_CFG80211_DISCONNECT,
11653 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011654 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
11655 __func__, hdd_device_modetoString(pAdapter->device_mode),
11656 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011657
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
11659 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070011660
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011661 status = wlan_hdd_validate_context(pHddCtx);
11662
11663 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11666 "%s: HDD context is not valid", __func__);
11667 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011669
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 if (NULL != pRoamProfile)
11671 {
11672 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011673 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
11674 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011676 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011678 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 switch(reason)
11680 {
11681 case WLAN_REASON_MIC_FAILURE:
11682 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
11683 break;
11684
11685 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
11686 case WLAN_REASON_DISASSOC_AP_BUSY:
11687 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
11688 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
11689 break;
11690
11691 case WLAN_REASON_PREV_AUTH_NOT_VALID:
11692 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053011693 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
11695 break;
11696
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 default:
11698 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
11699 break;
11700 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011701 pScanInfo = &pHddCtx->scan_info;
11702 if (pScanInfo->mScanPending)
11703 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011704 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011705 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011706 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053011707 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053011708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011709
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011710#ifdef FEATURE_WLAN_TDLS
11711 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011712 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011713 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011714 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
11715 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011716 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011717 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011718 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011719 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011720 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011721 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011722 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011723 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080011724 pAdapter->sessionId,
11725 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080011726 }
11727 }
11728#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011729 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011730 status = wlan_hdd_disconnect(pAdapter, reasonCode);
11731 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 {
11733 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011734 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 __func__, (int)status );
11736 return -EINVAL;
11737 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053011739 else
11740 {
11741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
11742 "called while in %d state", __func__,
11743 pHddStaCtx->conn_info.connState);
11744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 }
11746 else
11747 {
11748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
11749 }
11750
11751 return status;
11752}
11753
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011754static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
11755 struct net_device *dev,
11756 u16 reason
11757 )
11758{
11759 int ret;
11760 vos_ssr_protect(__func__);
11761 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
11762 vos_ssr_unprotect(__func__);
11763
11764 return ret;
11765}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053011766
Jeff Johnson295189b2012-06-20 16:38:30 -070011767/*
11768 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011769 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070011770 * settings in IBSS mode.
11771 */
11772static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 struct cfg80211_ibss_params *params
11775 )
11776{
11777 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011778 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11780 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011781
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 ENTER();
11783
11784 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070011785 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070011786
11787 if (params->ie_len && ( NULL != params->ie) )
11788 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011789 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11790 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 {
11792 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
11793 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11794 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011795 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011797 tDot11fIEWPA dot11WPAIE;
11798 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011799 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011800
Wilson Yang00256342013-10-10 23:13:38 -070011801 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011802 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
11803 params->ie_len, DOT11F_EID_WPA);
11804 if ( NULL != ie )
11805 {
11806 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
11807 // Unpack the WPA IE
11808 //Skip past the EID byte and length byte - and four byte WiFi OUI
11809 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
11810 &ie[2+4],
11811 ie[1] - 4,
11812 &dot11WPAIE);
11813 /*Extract the multicast cipher, the encType for unicast
11814 cipher for wpa-none is none*/
11815 encryptionType =
11816 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
11817 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070011819
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
11821
11822 if (0 > status)
11823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 __func__);
11826 return status;
11827 }
11828 }
11829
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 pWextState->roamProfile.AuthType.authType[0] =
11831 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 eCSR_AUTH_TYPE_OPEN_SYSTEM;
11833
11834 if (params->privacy)
11835 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836 /* Security enabled IBSS, At this time there is no information available
11837 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011839 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011841 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 *enable privacy bit in beacons */
11843
11844 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11845 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011846 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
11847 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11849 pWextState->roamProfile.EncryptionType.numEntries = 1;
11850 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070011851 return status;
11852}
11853
11854/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011855 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011856 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070011857 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011858static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 struct net_device *dev,
11860 struct cfg80211_ibss_params *params
11861 )
11862{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011863 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11865 tCsrRoamProfile *pRoamProfile;
11866 int status;
krunal sonie9002db2013-11-25 14:24:17 -080011867 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011868 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11869 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011870
11871 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11874 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
11875 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011876 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011877 "%s: device_mode = %s (%d)", __func__,
11878 hdd_device_modetoString(pAdapter->device_mode),
11879 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011881 status = wlan_hdd_validate_context(pHddCtx);
11882
11883 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11886 "%s: HDD context is not valid", __func__);
11887 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 }
11889
11890 if (NULL == pWextState)
11891 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011892 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 __func__);
11894 return -EIO;
11895 }
11896
Agarwal Ashish51325b52014-06-16 16:50:49 +053011897 if (vos_max_concurrent_connections_reached()) {
11898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11899 return -ECONNREFUSED;
11900 }
11901
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053011902 /*Try disconnecting if already in connected state*/
11903 status = wlan_hdd_try_disconnect(pAdapter);
11904 if ( 0 > status)
11905 {
11906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
11907 " IBSS connection"));
11908 return -EALREADY;
11909 }
11910
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 pRoamProfile = &pWextState->roamProfile;
11912
11913 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
11914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011915 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011916 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 return -EINVAL;
11918 }
11919
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011920 /* BSSID is provided by upper layers hence no need to AUTO generate */
11921 if (NULL != params->bssid) {
11922 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11923 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
11924 hddLog (VOS_TRACE_LEVEL_ERROR,
11925 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11926 return -EIO;
11927 }
11928 }
krunal sonie9002db2013-11-25 14:24:17 -080011929 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
11930 {
11931 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
11932 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
11933 {
11934 hddLog (VOS_TRACE_LEVEL_ERROR,
11935 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
11936 return -EIO;
11937 }
11938 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
11939 if (!params->bssid)
11940 {
11941 hddLog (VOS_TRACE_LEVEL_ERROR,
11942 "%s:Failed memory allocation", __func__);
11943 return -EIO;
11944 }
11945 vos_mem_copy((v_U8_t *)params->bssid,
11946 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
11947 VOS_MAC_ADDR_SIZE);
11948 alloc_bssid = VOS_TRUE;
11949 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070011950
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070011952 if (NULL !=
11953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11954 params->chandef.chan)
11955#else
11956 params->channel)
11957#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 {
11959 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011960 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
11961 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
11962 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11963 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011964
11965 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011966 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070011967 ieee80211_frequency_to_channel(
11968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
11969 params->chandef.chan->center_freq);
11970#else
11971 params->channel->center_freq);
11972#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011973
11974 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
11975 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
11978 __func__);
11979 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011981
11982 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011984 if (channelNum == validChan[indx])
11985 {
11986 break;
11987 }
11988 }
11989 if (indx >= numChans)
11990 {
11991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011992 __func__, channelNum);
11993 return -EINVAL;
11994 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011995 /* Set the Operational Channel */
11996 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
11997 channelNum);
11998 pRoamProfile->ChannelInfo.numOfChannels = 1;
11999 pHddStaCtx->conn_info.operationChannel = channelNum;
12000 pRoamProfile->ChannelInfo.ChannelList =
12001 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 }
12003
12004 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 if (status < 0)
12007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 __func__);
12010 return status;
12011 }
12012
12013 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012014 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012015 params->ssid_len, params->bssid,
12016 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012017
12018 if (0 > status)
12019 {
12020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
12021 return status;
12022 }
12023
krunal sonie9002db2013-11-25 14:24:17 -080012024 if (NULL != params->bssid &&
12025 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
12026 alloc_bssid == VOS_TRUE)
12027 {
12028 vos_mem_free(params->bssid);
12029 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012030 return 0;
12031}
12032
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012033static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12034 struct net_device *dev,
12035 struct cfg80211_ibss_params *params
12036 )
12037{
12038 int ret = 0;
12039
12040 vos_ssr_protect(__func__);
12041 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12042 vos_ssr_unprotect(__func__);
12043
12044 return ret;
12045}
12046
Jeff Johnson295189b2012-06-20 16:38:30 -070012047/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012048 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012049 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012051static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 struct net_device *dev
12053 )
12054{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012055 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012056 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12057 tCsrRoamProfile *pRoamProfile;
12058 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012059 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012060
12061 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012062
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012063 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12064 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12065 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012066 status = wlan_hdd_validate_context(pHddCtx);
12067
12068 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012069 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12071 "%s: HDD context is not valid", __func__);
12072 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012073 }
12074
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012075 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12076 hdd_device_modetoString(pAdapter->device_mode),
12077 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 if (NULL == pWextState)
12079 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012080 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 __func__);
12082 return -EIO;
12083 }
12084
12085 pRoamProfile = &pWextState->roamProfile;
12086
12087 /* Issue disconnect only if interface type is set to IBSS */
12088 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12089 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012090 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 __func__);
12092 return -EINVAL;
12093 }
12094
12095 /* Issue Disconnect request */
12096 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12097 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12098 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12099
12100 return 0;
12101}
12102
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012103static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12104 struct net_device *dev
12105 )
12106{
12107 int ret = 0;
12108
12109 vos_ssr_protect(__func__);
12110 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12111 vos_ssr_unprotect(__func__);
12112
12113 return ret;
12114}
12115
Jeff Johnson295189b2012-06-20 16:38:30 -070012116/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012117 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012118 * This function is used to set the phy parameters
12119 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12120 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012121static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 u32 changed)
12123{
12124 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12125 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012126 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012127
12128 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012129 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12130 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12131 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012132 status = wlan_hdd_validate_context(pHddCtx);
12133
12134 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012135 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12137 "%s: HDD context is not valid", __func__);
12138 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012139 }
12140
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12142 {
12143 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12144 WNI_CFG_RTS_THRESHOLD_STAMAX :
12145 wiphy->rts_threshold;
12146
12147 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012150 hddLog(VOS_TRACE_LEVEL_ERROR,
12151 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 __func__, rts_threshold);
12153 return -EINVAL;
12154 }
12155
12156 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
12157 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012158 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012160 hddLog(VOS_TRACE_LEVEL_ERROR,
12161 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 __func__, rts_threshold);
12163 return -EIO;
12164 }
12165
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 rts_threshold);
12168 }
12169
12170 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
12171 {
12172 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
12173 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
12174 wiphy->frag_threshold;
12175
12176 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 hddLog(VOS_TRACE_LEVEL_ERROR,
12180 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 frag_threshold);
12182 return -EINVAL;
12183 }
12184
12185 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
12186 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012187 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012189 hddLog(VOS_TRACE_LEVEL_ERROR,
12190 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 __func__, frag_threshold);
12192 return -EIO;
12193 }
12194
12195 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
12196 frag_threshold);
12197 }
12198
12199 if ((changed & WIPHY_PARAM_RETRY_SHORT)
12200 || (changed & WIPHY_PARAM_RETRY_LONG))
12201 {
12202 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
12203 wiphy->retry_short :
12204 wiphy->retry_long;
12205
12206 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
12207 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
12208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 __func__, retry_value);
12211 return -EINVAL;
12212 }
12213
12214 if (changed & WIPHY_PARAM_RETRY_SHORT)
12215 {
12216 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
12217 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012218 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012220 hddLog(VOS_TRACE_LEVEL_ERROR,
12221 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 __func__, retry_value);
12223 return -EIO;
12224 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012225 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 __func__, retry_value);
12227 }
12228 else if (changed & WIPHY_PARAM_RETRY_SHORT)
12229 {
12230 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
12231 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012232 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012234 hddLog(VOS_TRACE_LEVEL_ERROR,
12235 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 __func__, retry_value);
12237 return -EIO;
12238 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012239 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 __func__, retry_value);
12241 }
12242 }
12243
12244 return 0;
12245}
12246
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012247static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
12248 u32 changed)
12249{
12250 int ret;
12251
12252 vos_ssr_protect(__func__);
12253 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
12254 vos_ssr_unprotect(__func__);
12255
12256 return ret;
12257}
12258
Jeff Johnson295189b2012-06-20 16:38:30 -070012259/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012260 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 * This function is used to set the txpower
12262 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012263static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012264#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12265 struct wireless_dev *wdev,
12266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012267#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012269#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012270 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070012271#endif
12272 int dbm)
12273{
12274 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012275 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
12277 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012278 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012279
12280 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12282 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
12283 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012284 status = wlan_hdd_validate_context(pHddCtx);
12285
12286 if (0 != status)
12287 {
12288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12289 "%s: HDD context is not valid", __func__);
12290 return status;
12291 }
12292
12293 hHal = pHddCtx->hHal;
12294
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012295 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
12296 dbm, ccmCfgSetCallback,
12297 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012299 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
12301 return -EIO;
12302 }
12303
12304 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
12305 dbm);
12306
12307 switch(type)
12308 {
12309 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
12310 /* Fall through */
12311 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
12312 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
12313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
12315 __func__);
12316 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 }
12318 break;
12319 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 __func__);
12322 return -EOPNOTSUPP;
12323 break;
12324 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
12326 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 return -EIO;
12328 }
12329
12330 return 0;
12331}
12332
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012333static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
12334#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12335 struct wireless_dev *wdev,
12336#endif
12337#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12338 enum tx_power_setting type,
12339#else
12340 enum nl80211_tx_power_setting type,
12341#endif
12342 int dbm)
12343{
12344 int ret;
12345 vos_ssr_protect(__func__);
12346 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
12347#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12348 wdev,
12349#endif
12350#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
12351 type,
12352#else
12353 type,
12354#endif
12355 dbm);
12356 vos_ssr_unprotect(__func__);
12357
12358 return ret;
12359}
12360
Jeff Johnson295189b2012-06-20 16:38:30 -070012361/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012362 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 * This function is used to read the txpower
12364 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012365static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070012366#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12367 struct wireless_dev *wdev,
12368#endif
12369 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070012370{
12371
12372 hdd_adapter_t *pAdapter;
12373 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012374 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012375
Jeff Johnsone7245742012-09-05 17:12:55 -070012376 ENTER();
12377
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012378 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012379
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012380 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012381 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12383 "%s: HDD context is not valid", __func__);
12384 *dbm = 0;
12385 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012386 }
12387
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
12389 if (NULL == pAdapter)
12390 {
12391 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
12392 return -ENOENT;
12393 }
12394
12395 wlan_hdd_get_classAstats(pAdapter);
12396 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
12397
Jeff Johnsone7245742012-09-05 17:12:55 -070012398 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 return 0;
12400}
12401
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012402static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
12403#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12404 struct wireless_dev *wdev,
12405#endif
12406 int *dbm)
12407{
12408 int ret;
12409
12410 vos_ssr_protect(__func__);
12411 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
12412#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
12413 wdev,
12414#endif
12415 dbm);
12416 vos_ssr_unprotect(__func__);
12417
12418 return ret;
12419}
12420
12421
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012422static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 u8* mac, struct station_info *sinfo)
12424{
12425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12426 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12427 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053012428 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
12430 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
12431 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012432
12433 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
12434 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
12435 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
12436 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
12437 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
12438 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
12439 tANI_U16 maxRate = 0;
12440 tANI_U16 myRate;
12441 tANI_U16 currentRate = 0;
12442 tANI_U8 maxSpeedMCS = 0;
12443 tANI_U8 maxMCSIdx = 0;
12444 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053012445 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012446 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012447 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012448
Leo Chang6f8870f2013-03-26 18:11:36 -070012449#ifdef WLAN_FEATURE_11AC
12450 tANI_U32 vht_mcs_map;
12451 eDataRate11ACMaxMcs vhtMaxMcs;
12452#endif /* WLAN_FEATURE_11AC */
12453
Jeff Johnsone7245742012-09-05 17:12:55 -070012454 ENTER();
12455
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
12457 (0 == ssidlen))
12458 {
12459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
12460 " Invalid ssidlen, %d", __func__, ssidlen);
12461 /*To keep GUI happy*/
12462 return 0;
12463 }
12464
Mukul Sharma811205f2014-07-09 21:07:30 +053012465 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
12466 {
12467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12468 "%s: Roaming in progress, so unable to proceed this request", __func__);
12469 return 0;
12470 }
12471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012472 status = wlan_hdd_validate_context(pHddCtx);
12473
12474 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12477 "%s: HDD context is not valid", __func__);
12478 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012479 }
12480
Jeff Johnson295189b2012-06-20 16:38:30 -070012481
Kiet Lam3b17fc82013-09-27 05:24:08 +053012482 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
12483 sinfo->filled |= STATION_INFO_SIGNAL;
12484
c_hpothu09f19542014-05-30 21:53:31 +053012485 wlan_hdd_get_station_stats(pAdapter);
12486 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
12487
12488 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053012489 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
12490 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053012491 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053012492 {
12493 rate_flags = pAdapter->maxRateFlags;
12494 }
c_hpothu44ff4e02014-05-08 00:13:57 +053012495
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 //convert to the UI units of 100kbps
12497 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
12498
12499#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070012500 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 -070012501 sinfo->signal,
12502 pCfg->reportMaxLinkSpeed,
12503 myRate,
12504 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012505 (int) pCfg->linkSpeedRssiMid,
12506 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070012507 (int) rate_flags,
12508 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070012509#endif //LINKSPEED_DEBUG_ENABLED
12510
12511 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
12512 {
12513 // we do not want to necessarily report the current speed
12514 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
12515 {
12516 // report the max possible speed
12517 rssidx = 0;
12518 }
12519 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
12520 {
12521 // report the max possible speed with RSSI scaling
12522 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
12523 {
12524 // report the max possible speed
12525 rssidx = 0;
12526 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012527 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070012528 {
12529 // report middle speed
12530 rssidx = 1;
12531 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012532 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
12533 {
12534 // report middle speed
12535 rssidx = 2;
12536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 else
12538 {
12539 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070012540 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 }
12542 }
12543 else
12544 {
12545 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
12546 hddLog(VOS_TRACE_LEVEL_ERROR,
12547 "%s: Invalid value for reportMaxLinkSpeed: %u",
12548 __func__, pCfg->reportMaxLinkSpeed);
12549 rssidx = 0;
12550 }
12551
12552 maxRate = 0;
12553
12554 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012555 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
12556 OperationalRates, &ORLeng))
12557 {
12558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12559 /*To keep GUI happy*/
12560 return 0;
12561 }
12562
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 for (i = 0; i < ORLeng; i++)
12564 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012565 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 {
12567 /* Validate Rate Set */
12568 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
12569 {
12570 currentRate = supported_data_rate[j].supported_rate[rssidx];
12571 break;
12572 }
12573 }
12574 /* Update MAX rate */
12575 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12576 }
12577
12578 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012579 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
12580 ExtendedRates, &ERLeng))
12581 {
12582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12583 /*To keep GUI happy*/
12584 return 0;
12585 }
12586
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 for (i = 0; i < ERLeng; i++)
12588 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012589 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 {
12591 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
12592 {
12593 currentRate = supported_data_rate[j].supported_rate[rssidx];
12594 break;
12595 }
12596 }
12597 /* Update MAX rate */
12598 maxRate = (currentRate > maxRate)?currentRate:maxRate;
12599 }
c_hpothu79aab322014-07-14 21:11:01 +053012600
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012601 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053012602 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053012603 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053012604 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 {
c_hpothu79aab322014-07-14 21:11:01 +053012606 if (rate_flags & eHAL_TX_RATE_VHT80)
12607 mode = 2;
12608 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
12609 mode = 1;
12610 else
12611 mode = 0;
12612
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053012613 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
12614 MCSRates, &MCSLeng))
12615 {
12616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
12617 /*To keep GUI happy*/
12618 return 0;
12619 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070012621#ifdef WLAN_FEATURE_11AC
12622 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012623 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012625 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012626 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070012627 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012629 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012631 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012633 maxMCSIdx = 7;
12634 }
12635 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
12636 {
12637 maxMCSIdx = 8;
12638 }
12639 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
12640 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012641 //VHT20 is supporting 0~8
12642 if (rate_flags & eHAL_TX_RATE_VHT20)
12643 maxMCSIdx = 8;
12644 else
12645 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070012646 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012647
c_hpothu79aab322014-07-14 21:11:01 +053012648 if (0 != rssidx)/*check for scaled */
12649 {
12650 //get middle rate MCS index if rssi=1/2
12651 for (i=0; i <= maxMCSIdx; i++)
12652 {
12653 if (sinfo->signal <= rssiMcsTbl[mode][i])
12654 {
12655 maxMCSIdx = i;
12656 break;
12657 }
12658 }
12659 }
12660
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012661 if (rate_flags & eHAL_TX_RATE_VHT80)
12662 {
12663 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
12664 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
12665 }
12666 else if (rate_flags & eHAL_TX_RATE_VHT40)
12667 {
12668 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
12669 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
12670 }
12671 else if (rate_flags & eHAL_TX_RATE_VHT20)
12672 {
12673 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
12674 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
12675 }
12676
Leo Chang6f8870f2013-03-26 18:11:36 -070012677 maxSpeedMCS = 1;
12678 if (currentRate > maxRate)
12679 {
12680 maxRate = currentRate;
12681 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012682
Leo Chang6f8870f2013-03-26 18:11:36 -070012683 }
12684 else
12685#endif /* WLAN_FEATURE_11AC */
12686 {
12687 if (rate_flags & eHAL_TX_RATE_HT40)
12688 {
12689 rateFlag |= 1;
12690 }
12691 if (rate_flags & eHAL_TX_RATE_SGI)
12692 {
12693 rateFlag |= 2;
12694 }
12695
Girish Gowli01abcee2014-07-31 20:18:55 +053012696 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053012697 if (rssidx == 1 || rssidx == 2)
12698 {
12699 //get middle rate MCS index if rssi=1/2
12700 for (i=0; i <= 7; i++)
12701 {
12702 if (sinfo->signal <= rssiMcsTbl[mode][i])
12703 {
12704 temp = i+1;
12705 break;
12706 }
12707 }
12708 }
c_hpothu79aab322014-07-14 21:11:01 +053012709
12710 for (i = 0; i < MCSLeng; i++)
12711 {
Leo Chang6f8870f2013-03-26 18:11:36 -070012712 for (j = 0; j < temp; j++)
12713 {
12714 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
12715 {
12716 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
12717 break;
12718 }
12719 }
12720 if ((j < temp) && (currentRate > maxRate))
12721 {
12722 maxRate = currentRate;
12723 maxSpeedMCS = 1;
12724 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
12725 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 }
12727 }
12728 }
12729
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012730 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
12731 {
12732 maxRate = myRate;
12733 maxSpeedMCS = 1;
12734 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12735 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053012737 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 {
12739 maxRate = myRate;
12740 if (rate_flags & eHAL_TX_RATE_LEGACY)
12741 {
12742 maxSpeedMCS = 0;
12743 }
12744 else
12745 {
12746 maxSpeedMCS = 1;
12747 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
12748 }
12749 }
12750
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012751 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070012752 {
12753 sinfo->txrate.legacy = maxRate;
12754#ifdef LINKSPEED_DEBUG_ENABLED
12755 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
12756#endif //LINKSPEED_DEBUG_ENABLED
12757 }
12758 else
12759 {
12760 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070012761#ifdef WLAN_FEATURE_11AC
12762 sinfo->txrate.nss = 1;
12763 if (rate_flags & eHAL_TX_RATE_VHT80)
12764 {
12765 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012766 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070012767 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012768 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070012769 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012770 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12771 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12772 }
12773 else if (rate_flags & eHAL_TX_RATE_VHT20)
12774 {
12775 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12776 }
12777#endif /* WLAN_FEATURE_11AC */
12778 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
12779 {
12780 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12781 if (rate_flags & eHAL_TX_RATE_HT40)
12782 {
12783 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12784 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012785 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012786 if (rate_flags & eHAL_TX_RATE_SGI)
12787 {
12788 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12789 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053012790
Jeff Johnson295189b2012-06-20 16:38:30 -070012791#ifdef LINKSPEED_DEBUG_ENABLED
12792 pr_info("Reporting MCS rate %d flags %x\n",
12793 sinfo->txrate.mcs,
12794 sinfo->txrate.flags );
12795#endif //LINKSPEED_DEBUG_ENABLED
12796 }
12797 }
12798 else
12799 {
12800 // report current rate instead of max rate
12801
12802 if (rate_flags & eHAL_TX_RATE_LEGACY)
12803 {
12804 //provide to the UI in units of 100kbps
12805 sinfo->txrate.legacy = myRate;
12806#ifdef LINKSPEED_DEBUG_ENABLED
12807 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
12808#endif //LINKSPEED_DEBUG_ENABLED
12809 }
12810 else
12811 {
12812 //must be MCS
12813 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070012814#ifdef WLAN_FEATURE_11AC
12815 sinfo->txrate.nss = 1;
12816 if (rate_flags & eHAL_TX_RATE_VHT80)
12817 {
12818 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
12819 }
12820 else
12821#endif /* WLAN_FEATURE_11AC */
12822 {
12823 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
12824 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012825 if (rate_flags & eHAL_TX_RATE_SGI)
12826 {
12827 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
12828 }
12829 if (rate_flags & eHAL_TX_RATE_HT40)
12830 {
12831 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
12832 }
Leo Chang6f8870f2013-03-26 18:11:36 -070012833#ifdef WLAN_FEATURE_11AC
12834 else if (rate_flags & eHAL_TX_RATE_VHT80)
12835 {
12836 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
12837 }
12838#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070012839#ifdef LINKSPEED_DEBUG_ENABLED
12840 pr_info("Reporting actual MCS rate %d flags %x\n",
12841 sinfo->txrate.mcs,
12842 sinfo->txrate.flags );
12843#endif //LINKSPEED_DEBUG_ENABLED
12844 }
12845 }
12846 sinfo->filled |= STATION_INFO_TX_BITRATE;
12847
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012848 sinfo->tx_packets =
12849 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
12850 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
12851 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
12852 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
12853
12854 sinfo->tx_retries =
12855 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
12856 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
12857 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
12858 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
12859
12860 sinfo->tx_failed =
12861 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
12862 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
12863 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
12864 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
12865
12866 sinfo->filled |=
12867 STATION_INFO_TX_PACKETS |
12868 STATION_INFO_TX_RETRIES |
12869 STATION_INFO_TX_FAILED;
12870
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012871 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12872 TRACE_CODE_HDD_CFG80211_GET_STA,
12873 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070012874 EXIT();
12875 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012876}
12877
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012878static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
12879 u8* mac, struct station_info *sinfo)
12880{
12881 int ret;
12882
12883 vos_ssr_protect(__func__);
12884 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
12885 vos_ssr_unprotect(__func__);
12886
12887 return ret;
12888}
12889
12890static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070012891 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070012892{
12893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012894 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012896 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012897
Jeff Johnsone7245742012-09-05 17:12:55 -070012898 ENTER();
12899
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 if (NULL == pAdapter)
12901 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 return -ENODEV;
12904 }
12905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12907 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
12908 pAdapter->sessionId, timeout));
12909
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012911 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012912
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012913 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012914 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12916 "%s: HDD context is not valid", __func__);
12917 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012918 }
12919
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012920 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
12921 (TRUE == pHddCtx->hdd_wlan_suspended) &&
12922 (pHddCtx->cfg_ini->fhostArpOffload) &&
12923 (eConnectionState_Associated ==
12924 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12925 {
Amar Singhald53568e2013-09-26 11:03:45 -070012926
12927 hddLog(VOS_TRACE_LEVEL_INFO,
12928 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053012929 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012930 if (!VOS_IS_STATUS_SUCCESS(vos_status))
12931 {
12932 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012933 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053012934 __func__, vos_status);
12935 }
12936 }
12937
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 /**The get power cmd from the supplicant gets updated by the nl only
12939 *on successful execution of the function call
12940 *we are oppositely mapped w.r.t mode in the driver
12941 **/
12942 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
12943
Jeff Johnsone7245742012-09-05 17:12:55 -070012944 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 if (VOS_STATUS_E_FAILURE == vos_status)
12946 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12948 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012949 return -EINVAL;
12950 }
12951 return 0;
12952}
12953
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012954static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
12955 struct net_device *dev, bool mode, int timeout)
12956{
12957 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012958
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012959 vos_ssr_protect(__func__);
12960 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
12961 vos_ssr_unprotect(__func__);
12962
12963 return ret;
12964}
Jeff Johnson295189b2012-06-20 16:38:30 -070012965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012966static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
12967 struct net_device *netdev,
12968 u8 key_index)
12969{
12970 ENTER();
12971 return 0;
12972}
12973
Jeff Johnson295189b2012-06-20 16:38:30 -070012974static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012975 struct net_device *netdev,
12976 u8 key_index)
12977{
12978 int ret;
12979 vos_ssr_protect(__func__);
12980 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
12981 vos_ssr_unprotect(__func__);
12982 return ret;
12983}
12984#endif //LINUX_VERSION_CODE
12985
12986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
12987static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12988 struct net_device *dev,
12989 struct ieee80211_txq_params *params)
12990{
12991 ENTER();
12992 return 0;
12993}
12994#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12995static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
12996 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070012997{
Jeff Johnsone7245742012-09-05 17:12:55 -070012998 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 return 0;
13000}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013001#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013002
13003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13004static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013005 struct net_device *dev,
13006 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013007{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013008 int ret;
13009
13010 vos_ssr_protect(__func__);
13011 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13012 vos_ssr_unprotect(__func__);
13013 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013014}
13015#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13016static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13017 struct ieee80211_txq_params *params)
13018{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013019 int ret;
13020
13021 vos_ssr_protect(__func__);
13022 ret = __wlan_hdd_set_txq_params(wiphy, params);
13023 vos_ssr_unprotect(__func__);
13024 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013025}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013026#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013027
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013028static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013029 struct net_device *dev,
13030 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013031{
13032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013033 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013034 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013035 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013036 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013037 v_CONTEXT_t pVosContext = NULL;
13038 ptSapContext pSapCtx = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013039 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013041 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013044 return -EINVAL;
13045 }
13046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13048 TRACE_CODE_HDD_CFG80211_DEL_STA,
13049 pAdapter->sessionId, pAdapter->device_mode));
13050
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13052 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013053
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013054 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13057 "%s: HDD context is not valid", __func__);
13058 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013059 }
13060
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013062 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 )
13064 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013065 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13066 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13067 if(pSapCtx == NULL){
13068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13069 FL("psapCtx is NULL"));
13070 return -ENOENT;
13071 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013072 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 {
13074 v_U16_t i;
13075 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13076 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013077 if ((pSapCtx->aStaInfo[i].isUsed) &&
13078 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013080 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013081 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013082 ETHER_ADDR_LEN);
13083
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013085 "%s: Delete STA with MAC::"
13086 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013087 __func__,
13088 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13089 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013090 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013091 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013092 }
13093 }
13094 }
13095 else
13096 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013097
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013098 vos_status = hdd_softap_GetStaId(pAdapter,
13099 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013100 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13101 {
13102 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013103 "%s: Skip this DEL STA as this is not used::"
13104 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013105 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013106 return -ENOENT;
13107 }
13108
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013109 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013110 {
13111 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013112 "%s: Skip this DEL STA as deauth is in progress::"
13113 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013114 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013115 return -ENOENT;
13116 }
13117
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013118 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013119
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 hddLog(VOS_TRACE_LEVEL_INFO,
13121 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013122 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013123 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013124 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013125
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013126 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013127 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13128 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013129 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013130 hddLog(VOS_TRACE_LEVEL_INFO,
13131 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013132 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013133 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013134 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013135 return -ENOENT;
13136 }
13137
Jeff Johnson295189b2012-06-20 16:38:30 -070013138 }
13139 }
13140
13141 EXIT();
13142
13143 return 0;
13144}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013145
13146#ifdef CFG80211_DEL_STA_V2
13147static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13148 struct net_device *dev,
13149 struct station_del_parameters *param)
13150#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013151static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13152 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013153#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013154{
13155 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013156 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070013157
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013158 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013159
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013160#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013161 if (NULL == param) {
13162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013163 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013164 return -EINVAL;
13165 }
13166
13167 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
13168 param->subtype, &delStaParams);
13169
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013170#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013171 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013172 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013173#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013174 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
13175
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013176 vos_ssr_unprotect(__func__);
13177
13178 return ret;
13179}
13180
13181static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013182 struct net_device *dev, u8 *mac, struct station_parameters *params)
13183{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013184 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013185 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013186#ifdef FEATURE_WLAN_TDLS
13187 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013188 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13191 TRACE_CODE_HDD_CFG80211_ADD_STA,
13192 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013193 mask = params->sta_flags_mask;
13194
13195 set = params->sta_flags_set;
13196
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013197#ifdef WLAN_FEATURE_TDLS_DEBUG
13198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13199 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
13200 __func__, mask, set, MAC_ADDR_ARRAY(mac));
13201#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013202
13203 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13204 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013205 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013206 }
13207 }
13208#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080013209 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013210}
13211
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013212static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
13213 struct net_device *dev, u8 *mac, struct station_parameters *params)
13214{
13215 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013216
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013217 vos_ssr_protect(__func__);
13218 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
13219 vos_ssr_unprotect(__func__);
13220
13221 return ret;
13222}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013223#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070013224
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013225static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070013226 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013227{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13229 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013230 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013231 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013232 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013233 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070013234
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013235 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013236 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013237 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013239 return -EINVAL;
13240 }
13241
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013242 if (!pmksa) {
13243 hddLog(LOGE, FL("pmksa is NULL"));
13244 return -EINVAL;
13245 }
13246
13247 if (!pmksa->bssid || !pmksa->pmkid) {
13248 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
13249 pmksa->bssid, pmksa->pmkid);
13250 return -EINVAL;
13251 }
13252
13253 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
13254 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13255
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13257 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013258
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013259 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013260 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13262 "%s: HDD context is not valid", __func__);
13263 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013264 }
13265
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013266 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013267 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13268
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013269 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
13270 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013271
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013272 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013273 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013274 &pmk_id, 1, FALSE);
13275
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013276 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13277 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
13278 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013279
13280 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013281}
13282
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013283static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
13284 struct cfg80211_pmksa *pmksa)
13285{
13286 int ret;
13287
13288 vos_ssr_protect(__func__);
13289 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
13290 vos_ssr_unprotect(__func__);
13291
13292 return ret;
13293}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013294
Wilson Yang6507c4e2013-10-01 20:11:19 -070013295
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013296static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070013297 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013298{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13300 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013301 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013302 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013303
Wilson Yang6507c4e2013-10-01 20:11:19 -070013304 /* Validate pAdapter */
13305 if (NULL == pAdapter)
13306 {
13307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
13308 return -EINVAL;
13309 }
13310
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013311 if (!pmksa) {
13312 hddLog(LOGE, FL("pmksa is NULL"));
13313 return -EINVAL;
13314 }
13315
13316 if (!pmksa->bssid) {
13317 hddLog(LOGE, FL("pmksa->bssid is NULL"));
13318 return -EINVAL;
13319 }
13320
Kiet Lam98c46a12014-10-31 15:34:57 -070013321 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
13322 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
13323
Wilson Yang6507c4e2013-10-01 20:11:19 -070013324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13325 status = wlan_hdd_validate_context(pHddCtx);
13326
13327 if (0 != status)
13328 {
13329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13330 "%s: HDD context is not valid", __func__);
13331 return status;
13332 }
13333
13334 /*Retrieve halHandle*/
13335 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13336
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013337 /* Delete the PMKID CSR cache */
13338 if (eHAL_STATUS_SUCCESS !=
13339 sme_RoamDelPMKIDfromCache(halHandle,
13340 pAdapter->sessionId, pmksa->bssid, FALSE)) {
13341 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
13342 MAC_ADDR_ARRAY(pmksa->bssid));
13343 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013344 }
13345
Wilson Yangef657d32014-01-15 19:19:23 -080013346 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013347}
13348
Wilson Yang6507c4e2013-10-01 20:11:19 -070013349
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013350static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
13351 struct cfg80211_pmksa *pmksa)
13352{
13353 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013354
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013355 vos_ssr_protect(__func__);
13356 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
13357 vos_ssr_unprotect(__func__);
13358
13359 return ret;
13360
13361}
13362
13363static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013364{
Wilson Yang6507c4e2013-10-01 20:11:19 -070013365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13366 tHalHandle halHandle;
13367 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080013368 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013369
13370 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
13371
13372 /* Validate pAdapter */
13373 if (NULL == pAdapter)
13374 {
13375 hddLog(VOS_TRACE_LEVEL_ERROR,
13376 "%s: Invalid Adapter" ,__func__);
13377 return -EINVAL;
13378 }
13379
13380 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13381 status = wlan_hdd_validate_context(pHddCtx);
13382
13383 if (0 != status)
13384 {
13385 hddLog(VOS_TRACE_LEVEL_ERROR,
13386 "%s: HDD context is not valid", __func__);
13387 return status;
13388 }
13389
13390 /*Retrieve halHandle*/
13391 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13392
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053013393 /* Flush the PMKID cache in CSR */
13394 if (eHAL_STATUS_SUCCESS !=
13395 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
13396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
13397 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070013398 }
13399
Wilson Yangef657d32014-01-15 19:19:23 -080013400 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013401}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053013402
13403static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
13404{
13405 int ret;
13406
13407 vos_ssr_protect(__func__);
13408 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
13409 vos_ssr_unprotect(__func__);
13410
13411 return ret;
13412}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013413#endif
13414
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013415#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013416static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13417 struct net_device *dev,
13418 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013419{
13420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13421 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013422 hdd_context_t *pHddCtx;
13423 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013424
13425 if (NULL == pAdapter)
13426 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013428 return -ENODEV;
13429 }
13430
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013431 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13432 ret = wlan_hdd_validate_context(pHddCtx);
13433 if (0 != ret)
13434 {
13435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13436 "%s: HDD context is not valid", __func__);
13437 return ret;
13438 }
13439
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013440 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13441
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013442 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13443 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
13444 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013445 // Added for debug on reception of Re-assoc Req.
13446 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
13447 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013448 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013449 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080013450 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013451 }
13452
13453#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080013454 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013455 ftie->ie_len);
13456#endif
13457
13458 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013459 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13460 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013461 ftie->ie_len);
13462 return 0;
13463}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013464
13465static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
13466 struct net_device *dev,
13467 struct cfg80211_update_ft_ies_params *ftie)
13468{
13469 int ret;
13470
13471 vos_ssr_protect(__func__);
13472 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
13473 vos_ssr_unprotect(__func__);
13474
13475 return ret;
13476}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013477#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013478
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013479#ifdef FEATURE_WLAN_SCAN_PNO
13480
13481void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
13482 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
13483{
13484 int ret;
13485 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
13486 hdd_context_t *pHddCtx;
13487
Nirav Shah80830bf2013-12-31 16:35:12 +053013488 ENTER();
13489
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013490 if (NULL == pAdapter)
13491 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013493 "%s: HDD adapter is Null", __func__);
13494 return ;
13495 }
13496
13497 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13498 if (NULL == pHddCtx)
13499 {
13500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13501 "%s: HDD context is Null!!!", __func__);
13502 return ;
13503 }
13504
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013505 spin_lock(&pHddCtx->schedScan_lock);
13506 if (TRUE == pHddCtx->isWiphySuspended)
13507 {
13508 pHddCtx->isSchedScanUpdatePending = TRUE;
13509 spin_unlock(&pHddCtx->schedScan_lock);
13510 hddLog(VOS_TRACE_LEVEL_INFO,
13511 "%s: Update cfg80211 scan database after it resume", __func__);
13512 return ;
13513 }
13514 spin_unlock(&pHddCtx->schedScan_lock);
13515
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013516 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
13517
13518 if (0 > ret)
13519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
13520
13521 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13523 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013524}
13525
13526/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013527 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013528 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013529 */
13530static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
13531{
13532 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13533 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013534 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013535 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13536 int status = 0;
13537 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13538
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013539 /* The current firmware design does not allow PNO during any
13540 * active sessions. Hence, determine the active sessions
13541 * and return a failure.
13542 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013543 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
13544 {
13545 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013546 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013547
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013548 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
13549 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
13550 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
13551 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
13552 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053013553 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013554 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013555 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013556 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013557 }
13558 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13559 pAdapterNode = pNext;
13560 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013561 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013562}
13563
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013564void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
13565{
13566 hdd_adapter_t *pAdapter = callbackContext;
13567 hdd_context_t *pHddCtx;
13568
13569 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
13570 {
13571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13572 FL("Invalid adapter or adapter has invalid magic"));
13573 return;
13574 }
13575
13576 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13577 if (0 != wlan_hdd_validate_context(pHddCtx))
13578 {
13579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13580 FL("HDD context is not valid"));
13581 return;
13582 }
13583
c_hpothub53c45d2014-08-18 16:53:14 +053013584 if (VOS_STATUS_SUCCESS != status)
13585 {
13586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013587 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053013588 pHddCtx->isPnoEnable = FALSE;
13589 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013590
13591 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
13592 complete(&pAdapter->pno_comp_var);
13593}
13594
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013595/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013596 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
13597 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013598 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013599static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013600 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13601{
13602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13603 tpSirPNOScanReq pPnoRequest = NULL;
13604 hdd_context_t *pHddCtx;
13605 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013606 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053013607 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
13608 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013609 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13610 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013611 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013612 hdd_config_t *pConfig = NULL;
13613 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013614
13615 if (NULL == pAdapter)
13616 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013618 "%s: HDD adapter is Null", __func__);
13619 return -ENODEV;
13620 }
13621
13622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013623 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013624
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013625 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013626 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13628 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013629 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013630 }
13631
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013632 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013633 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13634 if (NULL == hHal)
13635 {
13636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13637 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013638 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013639 }
Sushant Kaushik2fe89932014-09-03 10:58:09 +053013640 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013641 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053013642 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013643 {
13644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13645 "%s: aborting the existing scan is unsuccessfull", __func__);
13646 return -EBUSY;
13647 }
13648
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013649 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013650 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053013651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053013652 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053013653 return -EBUSY;
13654 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013655
c_hpothu37f21312014-04-09 21:49:54 +053013656 if (TRUE == pHddCtx->isPnoEnable)
13657 {
13658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13659 FL("already PNO is enabled"));
13660 return -EBUSY;
13661 }
c_hpothu225aa7c2014-10-22 17:45:13 +053013662
13663 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
13664 {
13665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13666 "%s: abort ROC failed ", __func__);
13667 return -EBUSY;
13668 }
13669
c_hpothu37f21312014-04-09 21:49:54 +053013670 pHddCtx->isPnoEnable = TRUE;
13671
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013672 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13673 if (NULL == pPnoRequest)
13674 {
13675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13676 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053013677 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013678 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013679 }
13680
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053013681 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013682 pPnoRequest->enable = 1; /*Enable PNO */
13683 pPnoRequest->ucNetworksCount = request->n_match_sets;
13684
13685 if (( !pPnoRequest->ucNetworksCount ) ||
13686 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
13687 {
13688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013689 "%s: Network input is not correct %d Max Network supported is %d",
13690 __func__, pPnoRequest->ucNetworksCount,
13691 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013692 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013693 goto error;
13694 }
13695
13696 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
13697 {
13698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013699 "%s: Incorrect number of channels %d",
13700 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013701 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013702 goto error;
13703 }
13704
13705 /* Framework provides one set of channels(all)
13706 * common for all saved profile */
13707 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13708 channels_allowed, &num_channels_allowed))
13709 {
13710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13711 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013712 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013713 goto error;
13714 }
13715 /* Checking each channel against allowed channel list */
13716 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053013717 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013718 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013719 char chList [(request->n_channels*5)+1];
13720 int len;
13721 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013722 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013723 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013724 {
Nirav Shah80830bf2013-12-31 16:35:12 +053013725 if (request->channels[i]->hw_value == channels_allowed[indx])
13726 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013727 if ((!pConfig->enableDFSPnoChnlScan) &&
13728 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
13729 {
13730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13731 "%s : Dropping DFS channel : %d",
13732 __func__,channels_allowed[indx]);
13733 num_ignore_dfs_ch++;
13734 break;
13735 }
13736
Nirav Shah80830bf2013-12-31 16:35:12 +053013737 valid_ch[num_ch++] = request->channels[i]->hw_value;
13738 len += snprintf(chList+len, 5, "%d ",
13739 request->channels[i]->hw_value);
13740 break ;
13741 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013742 }
13743 }
Nirav Shah80830bf2013-12-31 16:35:12 +053013744 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013745
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053013746 /*If all channels are DFS and dropped, then ignore the PNO request*/
13747 if (num_ignore_dfs_ch == request->n_channels)
13748 {
13749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13750 "%s : All requested channels are DFS channels", __func__);
13751 ret = -EINVAL;
13752 goto error;
13753 }
13754 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013755 /* Filling per profile params */
13756 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
13757 {
13758 pPnoRequest->aNetworks[i].ssId.length =
13759 request->match_sets[i].ssid.ssid_len;
13760
13761 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
13762 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
13763 {
13764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013765 "%s: SSID Len %d is not correct for network %d",
13766 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013767 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013768 goto error;
13769 }
13770
13771 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
13772 request->match_sets[i].ssid.ssid,
13773 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053013774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13775 "%s: SSID of network %d is %s ", __func__,
13776 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013777 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
13778 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
13779 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
13780
13781 /*Copying list of valid channel into request */
13782 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
13783 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
13784
13785 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
13786 }
13787
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053013788 for (i = 0; i < request->n_ssids; i++)
13789 {
13790 j = 0;
13791 while (j < pPnoRequest->ucNetworksCount)
13792 {
13793 if ((pPnoRequest->aNetworks[j].ssId.length ==
13794 request->ssids[i].ssid_len) &&
13795 (0 == memcmp(pPnoRequest->aNetworks[j].ssId.ssId,
13796 request->ssids[i].ssid,
13797 pPnoRequest->aNetworks[j].ssId.length)))
13798 {
13799 pPnoRequest->aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
13800 break;
13801 }
13802 j++;
13803 }
13804 }
13805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13806 "Number of hidden networks being Configured = %d",
13807 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080013809 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053013810 if ((0 < request->ie_len) && (NULL != request->ie))
13811 {
13812 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
13813 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
13814 pPnoRequest->us24GProbeTemplateLen);
13815
13816 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
13817 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
13818 pPnoRequest->us5GProbeTemplateLen);
13819 }
13820
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053013821 /* Driver gets only one time interval which is hardcoded in
13822 * supplicant for 10000ms. Taking power consumption into account 6 timers
13823 * will be used, Timervalue is increased exponentially i.e 10,20,40,
13824 * 80,160,320 secs. And number of scan cycle for each timer
13825 * is configurable through INI param gPNOScanTimerRepeatValue.
13826 * If it is set to 0 only one timer will be used and PNO scan cycle
13827 * will be repeated after each interval specified by supplicant
13828 * till PNO is disabled.
13829 */
13830 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
13831 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
13832 else
13833 pPnoRequest->scanTimers.ucScanTimersCount =
13834 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
13835
13836 tempInterval = (request->interval)/1000;
13837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13838 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
13839 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
13840 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
13841 {
13842 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
13843 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
13844 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
13845 tempInterval *= 2;
13846 }
13847 //Repeat last timer until pno disabled.
13848 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
13849
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053013850 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013851
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013852 INIT_COMPLETION(pAdapter->pno_comp_var);
13853 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
13854 pPnoRequest->callbackContext = pAdapter;
13855 pAdapter->pno_req_status = 0;
13856
Nirav Shah80830bf2013-12-31 16:35:12 +053013857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13858 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
13859 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
13860 pPnoRequest->scanTimers.ucScanTimersCount);
13861
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013862 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
13863 pPnoRequest, pAdapter->sessionId,
13864 hdd_cfg80211_sched_scan_done_callback, pAdapter);
13865 if (eHAL_STATUS_SUCCESS != status)
13866 {
13867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053013868 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013869 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013870 goto error;
13871 }
13872
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013873 ret = wait_for_completion_timeout(
13874 &pAdapter->pno_comp_var,
13875 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
13876 if (0 >= ret)
13877 {
13878 // Did not receive the response for PNO enable in time.
13879 // Assuming the PNO enable was success.
13880 // Returning error from here, because we timeout, results
13881 // in side effect of Wifi (Wifi Setting) not to work.
13882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13883 FL("Timed out waiting for PNO to be Enabled"));
13884 ret = 0;
13885 goto error;
13886 }
13887
c_hpothu3c986b22014-07-09 14:45:09 +053013888 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013889 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053013890 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013891
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013892error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13894 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013895 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053013896 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013897 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013898}
13899
13900/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013901 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
13902 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013903 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053013904static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
13905 struct net_device *dev, struct cfg80211_sched_scan_request *request)
13906{
13907 int ret;
13908
13909 vos_ssr_protect(__func__);
13910 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
13911 vos_ssr_unprotect(__func__);
13912
13913 return ret;
13914}
13915
13916/*
13917 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
13918 * Function to disable PNO
13919 */
13920static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013921 struct net_device *dev)
13922{
13923 eHalStatus status = eHAL_STATUS_FAILURE;
13924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13925 hdd_context_t *pHddCtx;
13926 tHalHandle hHal;
13927 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013928 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013929
13930 ENTER();
13931
13932 if (NULL == pAdapter)
13933 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013935 "%s: HDD adapter is Null", __func__);
13936 return -ENODEV;
13937 }
13938
13939 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013940
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013941 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013942 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013944 "%s: HDD context is Null", __func__);
13945 return -ENODEV;
13946 }
13947
13948 /* The return 0 is intentional when isLogpInProgress and
13949 * isLoadUnloadInProgress. We did observe a crash due to a return of
13950 * failure in sched_scan_stop , especially for a case where the unload
13951 * of the happens at the same time. The function __cfg80211_stop_sched_scan
13952 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
13953 * success. If it returns a failure , then its next invocation due to the
13954 * clean up of the second interface will have the dev pointer corresponding
13955 * to the first one leading to a crash.
13956 */
13957 if (pHddCtx->isLogpInProgress)
13958 {
13959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13960 "%s: LOGP in Progress. Ignore!!!", __func__);
13961 return ret;
13962 }
13963
Mihir Shete18156292014-03-11 15:38:30 +053013964 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013965 {
13966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13967 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13968 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013969 }
13970
13971 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13972 if (NULL == hHal)
13973 {
13974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13975 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013976 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013977 }
13978
13979 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
13980 if (NULL == pPnoRequest)
13981 {
13982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13983 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013984 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053013985 }
13986
13987 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
13988 pPnoRequest->enable = 0; /* Disable PNO */
13989 pPnoRequest->ucNetworksCount = 0;
13990
13991 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
13992 pAdapter->sessionId,
13993 NULL, pAdapter);
13994 if (eHAL_STATUS_SUCCESS != status)
13995 {
13996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13997 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053013998 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053013999 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014000 }
c_hpothu37f21312014-04-09 21:49:54 +053014001 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014002
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014003error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014005 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014006 vos_mem_free(pPnoRequest);
14007
14008 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014009 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014010}
14011
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014012/*
14013 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14014 * NL interface to disable PNO
14015 */
14016static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14017 struct net_device *dev)
14018{
14019 int ret;
14020
14021 vos_ssr_protect(__func__);
14022 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14023 vos_ssr_unprotect(__func__);
14024
14025 return ret;
14026}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014027#endif /*FEATURE_WLAN_SCAN_PNO*/
14028
14029
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014030#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014031#if TDLS_MGMT_VERSION2
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014032static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014033 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014034 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
14035#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014036static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014037 u8 *peer, u8 action_code, u8 dialog_token,
14038 u16 status_code, const u8 *buf, size_t len)
14039#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014040{
14041
14042 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14043 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014044 u8 peerMac[6];
14045 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014046 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014047 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014048 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014049 int ret;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014050#if !(TDLS_MGMT_VERSION2)
14051 u32 peer_capability = 0;
14052#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014053 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014054
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014055 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14056 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
14057 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014058 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014061 "Invalid arguments");
14062 return -EINVAL;
14063 }
14064
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014065 if (pHddCtx->isLogpInProgress)
14066 {
14067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14068 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053014069 wlan_hdd_tdls_set_link_status(pAdapter,
14070 peer,
14071 eTDLS_LINK_IDLE,
14072 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014073 return -EBUSY;
14074 }
14075
Hoonki Lee27511902013-03-14 18:19:06 -070014076 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014077 {
Hoonki Lee27511902013-03-14 18:19:06 -070014078 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14079 "%s: TDLS mode is disabled OR not enabled in FW."
14080 MAC_ADDRESS_STR " action %d declined.",
14081 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014082 return -ENOTSUPP;
14083 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014084
Hoonki Lee27511902013-03-14 18:19:06 -070014085 /* other than teardown frame, other mgmt frames are not sent if disabled */
14086 if (SIR_MAC_TDLS_TEARDOWN != action_code)
14087 {
14088 /* if tdls_mode is disabled to respond to peer's request */
14089 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
14090 {
14091 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
14092 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014093 " TDLS mode is disabled. action %d declined.",
14094 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070014095
14096 return -ENOTSUPP;
14097 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014098
14099 if (vos_max_concurrent_connections_reached())
14100 {
14101 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14102 return -EINVAL;
14103 }
Hoonki Lee27511902013-03-14 18:19:06 -070014104 }
14105
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014106 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
14107 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014108 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014109 {
14110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014111 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014112 " TDLS setup is ongoing. action %d declined.",
14113 __func__, MAC_ADDR_ARRAY(peer), action_code);
14114 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014115 }
14116 }
14117
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014118 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
14119 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080014120 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014121 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14122 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014123 {
14124 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
14125 we return error code at 'add_station()'. Hence we have this
14126 check again in addtion to add_station().
14127 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014128 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080014129 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14131 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014132 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
14133 __func__, MAC_ADDR_ARRAY(peer), action_code,
14134 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053014135 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080014136 }
14137 else
14138 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014139 /* maximum reached. tweak to send error code to peer and return
14140 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014141 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14143 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014144 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
14145 __func__, MAC_ADDR_ARRAY(peer), status_code,
14146 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070014147 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014148 /* fall through to send setup resp with failure status
14149 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080014150 }
14151 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014152 else
14153 {
14154 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014155 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014156 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014157 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070014159 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
14160 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014161 return -EPERM;
14162 }
14163 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014164 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014165 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014166
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014167#ifdef WLAN_FEATURE_TDLS_DEBUG
14168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014169 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014170 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
14171 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014172#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014173
Hoonki Leea34dd892013-02-05 22:56:02 -080014174 /*Except teardown responder will not be used so just make 0*/
14175 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014176 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080014177 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014178
14179 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053014180 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014181
14182 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
14183 responder = pTdlsPeer->is_responder;
14184 else
Hoonki Leea34dd892013-02-05 22:56:02 -080014185 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070014186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053014187 "%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 -070014188 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
14189 dialog_token, status_code, len);
14190 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080014191 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014192 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014193
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014194 /* For explicit trigger of DIS_REQ come out of BMPS for
14195 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070014196 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014197 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
14198 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070014199 {
14200 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
14201 {
14202 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014203 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070014204 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
14205 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053014206 if (SIR_MAC_TDLS_DIS_REQ != action_code)
14207 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070014208 }
14209
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014210 /* make sure doesn't call send_mgmt() while it is pending */
14211 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
14212 {
14213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014214 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014215 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014216 ret = -EBUSY;
14217 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014218 }
14219
14220 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014221 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
14222
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014223 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053014224 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014225
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014226 if (VOS_STATUS_SUCCESS != status)
14227 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14229 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014230 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014231 ret = -EINVAL;
14232 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014233 }
14234
Hoonki Leed37cbb32013-04-20 00:31:14 -070014235 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
14236 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
14237
14238 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014239 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070014240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014241 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070014242 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014243 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080014244
14245 if (pHddCtx->isLogpInProgress)
14246 {
14247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14248 "%s: LOGP in Progress. Ignore!!!", __func__);
14249 return -EAGAIN;
14250 }
14251
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014252 ret = -EINVAL;
14253 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014254 }
14255
Gopichand Nakkala05922802013-03-14 12:23:19 -070014256 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070014257 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014258 ret = max_sta_failed;
14259 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070014260 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014261
Hoonki Leea34dd892013-02-05 22:56:02 -080014262 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
14263 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014264 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014265 }
14266 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
14267 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014268 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080014269 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014270
14271 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014272
14273tx_failed:
14274 /* add_station will be called before sending TDLS_SETUP_REQ and
14275 * TDLS_SETUP_RSP and as part of add_station driver will enable
14276 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
14277 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
14278 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
14279 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
14280 */
14281
14282 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
14283 (SIR_MAC_TDLS_SETUP_RSP == action_code))
14284 wlan_hdd_tdls_check_bmps(pAdapter);
14285 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014286}
14287
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014288#if TDLS_MGMT_VERSION2
14289static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14290 u8 *peer, u8 action_code, u8 dialog_token,
14291 u16 status_code, u32 peer_capability,
14292 const u8 *buf, size_t len)
14293#else
14294static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
14295 u8 *peer, u8 action_code, u8 dialog_token,
14296 u16 status_code, const u8 *buf, size_t len)
14297#endif
14298{
14299 int ret;
14300
14301 vos_ssr_protect(__func__);
14302#if TDLS_MGMT_VERSION2
14303 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14304 status_code, peer_capability, buf, len);
14305#else
14306 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, dialog_token,
14307 status_code, buf, len);
14308#endif
14309 vos_ssr_unprotect(__func__);
14310
14311 return ret;
14312}
Atul Mittal115287b2014-07-08 13:26:33 +053014313
14314int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
14315 u8 *peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014316 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053014317 cfg80211_exttdls_callback callback)
14318{
14319
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014320 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053014321 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14323 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
14324 __func__, MAC_ADDR_ARRAY(peer));
14325
14326 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14327 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14328
14329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14330 " %s TDLS External control and Implicit Trigger not enabled ",
14331 __func__);
14332 return -ENOTSUPP;
14333 }
14334
14335 /* To cater the requirement of establishing the TDLS link
14336 * irrespective of the data traffic , get an entry of TDLS peer.
14337 */
14338 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
14339 if (pTdlsPeer == NULL) {
14340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14341 "%s: peer " MAC_ADDRESS_STR " not existing",
14342 __func__, MAC_ADDR_ARRAY(peer));
14343 return -EINVAL;
14344 }
14345
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014346 if (NULL != tdls_peer_params)
14347 {
14348 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
14349 pTdlsPeer->peerParams.global_operating_class =
14350 tdls_peer_params->global_operating_class;
14351 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
14352 pTdlsPeer->peerParams.min_bandwidth_kbps =
14353 tdls_peer_params->min_bandwidth_kbps;
14354 /* check configured channel is valid and non dfs */
14355 if (sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
14356 tdls_peer_params->channel))
14357 {
14358 pTdlsPeer->isOffChannelConfigured = TRUE;
14359 }
14360 else
14361 {
14362 pTdlsPeer->isOffChannelConfigured = FALSE;
14363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14364 "%s: Configured Tdls Off Channel is not valid", __func__);
14365
14366 }
14367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14368 "%s: tdls_off_channel %d isOffChannelConfigured %d",
14369 __func__, pTdlsPeer->peerParams.channel,
14370 pTdlsPeer->isOffChannelConfigured);
14371 }
14372 else
14373 {
14374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14375 "%s: Invalid TDLS Peer Params", __func__);
14376 }
14377
Atul Mittal115287b2014-07-08 13:26:33 +053014378 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
14379
14380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14381 " %s TDLS Add Force Peer Failed",
14382 __func__);
14383 return -EINVAL;
14384 }
14385 /*EXT TDLS*/
14386
14387 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
14388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14389 " %s TDLS set callback Failed",
14390 __func__);
14391 return -EINVAL;
14392 }
14393
14394 return(0);
14395
14396}
14397
14398int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer)
14399{
14400
14401 hddTdlsPeer_t *pTdlsPeer;
14402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14404 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
14405 __func__, MAC_ADDR_ARRAY(peer));
14406
14407 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
14408 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
14409
14410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14411 " %s TDLS External control and Implicit Trigger not enabled ",
14412 __func__);
14413 return -ENOTSUPP;
14414 }
14415
14416
14417 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14418
14419 if ( NULL == pTdlsPeer ) {
14420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
14421 " peer not exsting",
14422 __func__, MAC_ADDR_ARRAY(peer));
14423 return -EINVAL;
14424 }
14425 else {
14426 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
14427 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014428 /* if channel switch is configured, reset
14429 the channel for this peer */
14430 if (TRUE == pTdlsPeer->isOffChannelConfigured)
14431 {
14432 pTdlsPeer->peerParams.channel = 0;
14433 pTdlsPeer->isOffChannelConfigured = FALSE;
14434 }
Atul Mittal115287b2014-07-08 13:26:33 +053014435 }
14436
14437 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
14438 return -EINVAL;
14439
14440 /*EXT TDLS*/
14441
14442 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
14443
14444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14445 " %s TDLS set callback Failed",
14446 __func__);
14447 return -EINVAL;
14448 }
14449 return(0);
14450
14451}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014452static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014453 u8 *peer, enum nl80211_tdls_operation oper)
14454{
14455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14456 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014457 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014458 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014459
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14461 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
14462 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014463 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014464 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014466 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014467 return -EINVAL;
14468 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014469
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014470 status = wlan_hdd_validate_context(pHddCtx);
14471
14472 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014473 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14475 "%s: HDD context is not valid", __func__);
14476 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080014477 }
14478
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014479
14480 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014481 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014482 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080014483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070014484 "TDLS Disabled in INI OR not enabled in FW. "
14485 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014486 return -ENOTSUPP;
14487 }
14488
14489 switch (oper) {
14490 case NL80211_TDLS_ENABLE_LINK:
14491 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014492 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014493 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014494 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053014495 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014496 tANI_U16 numCurrTdlsPeers = 0;
14497 hddTdlsPeer_t *connPeer = NULL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014498
Sunil Dutt41de4e22013-11-14 18:09:02 +053014499 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014500 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053014501 if ( NULL == pTdlsPeer ) {
14502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14503 " (oper %d) not exsting. ignored",
14504 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14505 return -EINVAL;
14506 }
14507
14508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14509 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14510 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14511 "NL80211_TDLS_ENABLE_LINK");
14512
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070014513 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
14514 {
14515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
14516 MAC_ADDRESS_STR " failed",
14517 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
14518 return -EINVAL;
14519 }
14520
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014521 /* TDLS Off Channel, Disable tdls channel switch,
14522 when there are more than one tdls link */
14523 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14524 if (numCurrTdlsPeers == 1)
14525 {
14526 /* get connected peer and send disable tdls off chan */
14527 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14528 if (connPeer && (connPeer->isOffChannelConfigured == TRUE))
14529 {
14530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14531 "%s: More then one peer connected, Disable "
14532 "TDLS channel switch", __func__);
14533
14534 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14535 pAdapter->sessionId,
14536 connPeer->peerMac,
14537 connPeer->peerParams.channel,
14538 TDLS_OFF_CHANNEL_BW_OFFSET,
14539 TDLS_CHANNEL_SWITCH_DISABLE);
14540 }
14541 else
14542 {
14543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14544 "%s: No TDLS Connected Peer or "
14545 "isOffChannelConfigured %d",
14546 __func__,
14547 (connPeer ? connPeer->isOffChannelConfigured : -1));
14548 }
14549 }
14550
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014551 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014552 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014553 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053014554
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014555 if (0 != wlan_hdd_tdls_get_link_establish_params(
14556 pAdapter, peer,&tdlsLinkEstablishParams)) {
14557 return -EINVAL;
14558 }
14559 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014560
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053014561 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
14562 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
14563 /* Send TDLS peer UAPSD capabilities to the firmware and
14564 * register with the TL on after the response for this operation
14565 * is received .
14566 */
14567 ret = wait_for_completion_interruptible_timeout(
14568 &pAdapter->tdls_link_establish_req_comp,
14569 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
14570 if (ret <= 0)
14571 {
14572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14573 "%s: Link Establish Request Faled Status %ld",
14574 __func__, ret);
14575 return -EINVAL;
14576 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014577 }
Atul Mittal115287b2014-07-08 13:26:33 +053014578 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14579 eTDLS_LINK_CONNECTED,
14580 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053014581 staDesc.ucSTAId = pTdlsPeer->staId;
14582 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
14583 WLANTL_UpdateTdlsSTAClient(pHddCtx->pvosContext,
14584 &staDesc);
14585
14586
Gopichand Nakkala471708b2013-06-04 20:03:01 +053014587 /* Mark TDLS client Authenticated .*/
14588 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
14589 pTdlsPeer->staId,
14590 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014591 if (VOS_STATUS_SUCCESS == status)
14592 {
Hoonki Lee14621352013-04-16 17:51:19 -070014593 if (pTdlsPeer->is_responder == 0)
14594 {
14595 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
14596
14597 wlan_hdd_tdls_timer_restart(pAdapter,
14598 &pTdlsPeer->initiatorWaitTimeoutTimer,
14599 WAIT_TIME_TDLS_INITIATOR);
14600 /* suspend initiator TX until it receives direct packet from the
14601 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
14602 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14603 &staId, NULL);
14604 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014605 wlan_hdd_tdls_increment_peer_count(pAdapter);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014606
14607 /* TDLS Off Channel, Enable tdls channel switch,
14608 when their is only one tdls link and it supports */
14609 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14610 if ((numCurrTdlsPeers == 1) &&
14611 (TRUE == pTdlsPeer->isOffChannelSupported) &&
14612 (TRUE == pTdlsPeer->isOffChannelConfigured))
14613 {
14614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14615 "%s: Send TDLS channel switch request for channel %d",
14616 __func__, pTdlsPeer->peerParams.channel);
14617 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14618 pAdapter->sessionId,
14619 pTdlsPeer->peerMac,
14620 pTdlsPeer->peerParams.channel,
14621 TDLS_OFF_CHANNEL_BW_OFFSET,
14622 TDLS_CHANNEL_SWITCH_ENABLE);
14623 }
14624 else
14625 {
14626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14627 "%s: TDLS channel switch request not sent"
14628 " numCurrTdlsPeers %d "
14629 "isOffChannelSupported %d "
14630 "isOffChannelConfigured %d",
14631 __func__, numCurrTdlsPeers,
14632 pTdlsPeer->isOffChannelSupported,
14633 pTdlsPeer->isOffChannelConfigured);
14634 }
14635
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070014636 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014637 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014638
14639 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014640 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
14641 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014642 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053014643 int ac;
14644 uint8 ucAc[4] = { WLANTL_AC_VO,
14645 WLANTL_AC_VI,
14646 WLANTL_AC_BK,
14647 WLANTL_AC_BE };
14648 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
14649 for(ac=0; ac < 4; ac++)
14650 {
14651 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
14652 pTdlsPeer->staId, ucAc[ac],
14653 tlTid[ac], tlTid[ac], 0, 0,
14654 WLANTL_BI_DIR );
14655 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053014656 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014657 }
14658
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014659 }
14660 break;
14661 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080014662 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014663 tANI_U16 numCurrTdlsPeers = 0;
14664 hddTdlsPeer_t *connPeer = NULL;
14665
Sunil Dutt41de4e22013-11-14 18:09:02 +053014666 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
14667
14668 if ( NULL == pTdlsPeer ) {
14669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
14670 " (oper %d) not exsting. ignored",
14671 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
14672 return -EINVAL;
14673 }
14674
14675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14676 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
14677 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
14678 "NL80211_TDLS_DISABLE_LINK");
14679
Hoonki Lee5305c3a2013-04-29 23:28:59 -070014680 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080014681 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014682 long status;
14683
Atul Mittal271a7652014-09-12 13:18:22 +053014684
14685 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
14686 eTDLS_LINK_TEARING,
14687 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
14688 eTDLS_LINK_UNSPECIFIED:
14689 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014690 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
14691
Lee Hoonkic1262f22013-01-24 21:59:00 -080014692 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
14693 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014694
14695 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
14696 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053014697 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053014698 eTDLS_LINK_IDLE,
14699 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014700 if (status <= 0)
14701 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070014702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14703 "%s: Del station failed status %ld",
14704 __func__, status);
14705 return -EPERM;
14706 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014707
14708 /* TDLS Off Channel, Enable tdls channel switch,
14709 when their is only one tdls link and it supports */
14710 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
14711 if (numCurrTdlsPeers == 1)
14712 {
14713 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
14714 if ((connPeer) &&
14715 (connPeer->isOffChannelSupported == TRUE) &&
14716 (connPeer->isOffChannelConfigured == TRUE))
14717 {
14718 sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
14719 pAdapter->sessionId,
14720 connPeer->peerMac,
14721 connPeer->peerParams.channel,
14722 TDLS_OFF_CHANNEL_BW_OFFSET,
14723 TDLS_CHANNEL_SWITCH_ENABLE);
14724 }
14725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14726 "%s: TDLS channel switch "
14727 "isOffChannelSupported %d "
14728 "isOffChannelConfigured %d",
14729 __func__,
14730 (connPeer ? connPeer->isOffChannelSupported : -1),
14731 (connPeer ? connPeer->isOffChannelConfigured : -1));
14732 }
14733 else
14734 {
14735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14736 "%s: TDLS channel switch request not sent "
14737 "numCurrTdlsPeers %d ",
14738 __func__, numCurrTdlsPeers);
14739 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014740 }
14741 else
14742 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14744 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080014745 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080014746 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014747 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014748 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014749 {
Atul Mittal115287b2014-07-08 13:26:33 +053014750 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014751
Atul Mittal115287b2014-07-08 13:26:33 +053014752 if (0 != status)
14753 {
14754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14755 "%s: Error in TDLS Teardown", __func__);
14756 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014757 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053014758 break;
14759 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014760 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053014761 {
Atul Mittal115287b2014-07-08 13:26:33 +053014762 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
14763 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053014764 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053014765 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053014766
Atul Mittal115287b2014-07-08 13:26:33 +053014767 if (0 != status)
14768 {
14769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14770 "%s: Error in TDLS Setup", __func__);
14771 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053014772 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053014773 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053014774 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014775 case NL80211_TDLS_DISCOVERY_REQ:
14776 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14778 "%s: We don't support in-driver setup/teardown/discovery "
14779 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014780 return -ENOTSUPP;
14781 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14783 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014784 return -ENOTSUPP;
14785 }
14786 return 0;
14787}
Chilam NG571c65a2013-01-19 12:27:36 +053014788
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014789static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
14790 u8 *peer, enum nl80211_tdls_operation oper)
14791{
14792 int ret;
14793
14794 vos_ssr_protect(__func__);
14795 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
14796 vos_ssr_unprotect(__func__);
14797
14798 return ret;
14799}
14800
Chilam NG571c65a2013-01-19 12:27:36 +053014801int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
14802 struct net_device *dev, u8 *peer)
14803{
Arif Hussaina7c8e412013-11-20 11:06:42 -080014804 hddLog(VOS_TRACE_LEVEL_INFO,
14805 "tdls send discover req: "MAC_ADDRESS_STR,
14806 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053014807
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014808#if TDLS_MGMT_VERSION2
14809 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14810 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
14811#else
Chilam NG571c65a2013-01-19 12:27:36 +053014812 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
14813 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014814#endif
Chilam NG571c65a2013-01-19 12:27:36 +053014815}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014816#endif
14817
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014818#ifdef WLAN_FEATURE_GTK_OFFLOAD
14819/*
14820 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
14821 * Callback rountine called upon receiving response for
14822 * get offload info
14823 */
14824void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
14825 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
14826{
14827
14828 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014829 tANI_U8 tempReplayCounter[8];
14830 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014831
14832 ENTER();
14833
14834 if (NULL == pAdapter)
14835 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014837 "%s: HDD adapter is Null", __func__);
14838 return ;
14839 }
14840
14841 if (NULL == pGtkOffloadGetInfoRsp)
14842 {
14843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14844 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
14845 return ;
14846 }
14847
14848 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
14849 {
14850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14851 "%s: wlan Failed to get replay counter value",
14852 __func__);
14853 return ;
14854 }
14855
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014856 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14857 /* Update replay counter */
14858 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
14859 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14860
14861 {
14862 /* changing from little to big endian since supplicant
14863 * works on big endian format
14864 */
14865 int i;
14866 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
14867
14868 for (i = 0; i < 8; i++)
14869 {
14870 tempReplayCounter[7-i] = (tANI_U8)p[i];
14871 }
14872 }
14873
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014874 /* Update replay counter to NL */
14875 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014876 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014877}
14878
14879/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014880 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014881 * This function is used to offload GTK rekeying job to the firmware.
14882 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014883int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014884 struct cfg80211_gtk_rekey_data *data)
14885{
14886 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14887 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14888 hdd_station_ctx_t *pHddStaCtx;
14889 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014890 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014891 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014892 eHalStatus status = eHAL_STATUS_FAILURE;
14893
14894 ENTER();
14895
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014896
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014897 if (NULL == pAdapter)
14898 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014900 "%s: HDD adapter is Null", __func__);
14901 return -ENODEV;
14902 }
14903
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014904 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14905 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
14906 pAdapter->sessionId, pAdapter->device_mode));
14907
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014908 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014909
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014910 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014911 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14913 "%s: HDD context is not valid", __func__);
14914 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014915 }
14916
14917 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14918 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14919 if (NULL == hHal)
14920 {
14921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14922 "%s: HAL context is Null!!!", __func__);
14923 return -EAGAIN;
14924 }
14925
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014926 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
14927 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
14928 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
14929 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014930 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014931 {
14932 /* changing from big to little endian since driver
14933 * works on little endian format
14934 */
14935 tANI_U8 *p =
14936 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
14937 int i;
14938
14939 for (i = 0; i < 8; i++)
14940 {
14941 p[7-i] = data->replay_ctr[i];
14942 }
14943 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014944
14945 if (TRUE == pHddCtx->hdd_wlan_suspended)
14946 {
14947 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014948 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
14949 sizeof (tSirGtkOffloadParams));
14950 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014951 pAdapter->sessionId);
14952
14953 if (eHAL_STATUS_SUCCESS != status)
14954 {
14955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14956 "%s: sme_SetGTKOffload failed, returned %d",
14957 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014958
14959 /* Need to clear any trace of key value in the memory.
14960 * Thus zero out the memory even though it is local
14961 * variable.
14962 */
14963 vos_mem_zero(&hddGtkOffloadReqParams,
14964 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014965 return status;
14966 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14968 "%s: sme_SetGTKOffload successfull", __func__);
14969 }
14970 else
14971 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14973 "%s: wlan not suspended GTKOffload request is stored",
14974 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014975 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014976
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053014977 /* Need to clear any trace of key value in the memory.
14978 * Thus zero out the memory even though it is local
14979 * variable.
14980 */
14981 vos_mem_zero(&hddGtkOffloadReqParams,
14982 sizeof(hddGtkOffloadReqParams));
14983
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053014984 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014985}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014986
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014987int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
14988 struct cfg80211_gtk_rekey_data *data)
14989{
14990 int ret;
14991
14992 vos_ssr_protect(__func__);
14993 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
14994 vos_ssr_unprotect(__func__);
14995
14996 return ret;
14997}
14998#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014999/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015000 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015001 * This function is used to set access control policy
15002 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015003static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15004 struct net_device *dev,
15005 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015006{
15007 int i;
15008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15009 hdd_hostapd_state_t *pHostapdState;
15010 tsap_Config_t *pConfig;
15011 v_CONTEXT_t pVosContext = NULL;
15012 hdd_context_t *pHddCtx;
15013 int status;
15014
15015 ENTER();
15016
15017 if (NULL == pAdapter)
15018 {
15019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15020 "%s: HDD adapter is Null", __func__);
15021 return -ENODEV;
15022 }
15023
15024 if (NULL == params)
15025 {
15026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15027 "%s: params is Null", __func__);
15028 return -EINVAL;
15029 }
15030
15031 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15032 status = wlan_hdd_validate_context(pHddCtx);
15033
15034 if (0 != status)
15035 {
15036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15037 "%s: HDD context is not valid", __func__);
15038 return status;
15039 }
15040
15041 pVosContext = pHddCtx->pvosContext;
15042 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
15043
15044 if (NULL == pHostapdState)
15045 {
15046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15047 "%s: pHostapdState is Null", __func__);
15048 return -EINVAL;
15049 }
15050
15051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
15052 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
15053
15054 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
15055 {
15056 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
15057
15058 /* default value */
15059 pConfig->num_accept_mac = 0;
15060 pConfig->num_deny_mac = 0;
15061
15062 /**
15063 * access control policy
15064 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
15065 * listed in hostapd.deny file.
15066 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
15067 * listed in hostapd.accept file.
15068 */
15069 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
15070 {
15071 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
15072 }
15073 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
15074 {
15075 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
15076 }
15077 else
15078 {
15079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15080 "%s:Acl Policy : %d is not supported",
15081 __func__, params->acl_policy);
15082 return -ENOTSUPP;
15083 }
15084
15085 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
15086 {
15087 pConfig->num_accept_mac = params->n_acl_entries;
15088 for (i = 0; i < params->n_acl_entries; i++)
15089 {
15090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15091 "** Add ACL MAC entry %i in WhiletList :"
15092 MAC_ADDRESS_STR, i,
15093 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15094
15095 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
15096 sizeof(qcmacaddr));
15097 }
15098 }
15099 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
15100 {
15101 pConfig->num_deny_mac = params->n_acl_entries;
15102 for (i = 0; i < params->n_acl_entries; i++)
15103 {
15104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15105 "** Add ACL MAC entry %i in BlackList :"
15106 MAC_ADDRESS_STR, i,
15107 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
15108
15109 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
15110 sizeof(qcmacaddr));
15111 }
15112 }
15113
15114 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
15115 {
15116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15117 "%s: SAP Set Mac Acl fail", __func__);
15118 return -EINVAL;
15119 }
15120 }
15121 else
15122 {
15123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015124 "%s: Invalid device_mode = %s (%d)",
15125 __func__, hdd_device_modetoString(pAdapter->device_mode),
15126 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015127 return -EINVAL;
15128 }
15129
15130 return 0;
15131}
15132
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015133static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
15134 struct net_device *dev,
15135 const struct cfg80211_acl_data *params)
15136{
15137 int ret;
15138 vos_ssr_protect(__func__);
15139 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
15140 vos_ssr_unprotect(__func__);
15141
15142 return ret;
15143}
15144
Leo Chang9056f462013-08-01 19:21:11 -070015145#ifdef WLAN_NL80211_TESTMODE
15146#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070015147void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070015148(
15149 void *pAdapter,
15150 void *indCont
15151)
15152{
Leo Changd9df8aa2013-09-26 13:32:26 -070015153 tSirLPHBInd *lphbInd;
15154 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053015155 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070015156
15157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015158 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070015159
c_hpothu73f35e62014-04-18 13:40:08 +053015160 if (pAdapter == NULL)
15161 {
15162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15163 "%s: pAdapter is NULL\n",__func__);
15164 return;
15165 }
15166
Leo Chang9056f462013-08-01 19:21:11 -070015167 if (NULL == indCont)
15168 {
15169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070015170 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070015171 return;
15172 }
15173
c_hpothu73f35e62014-04-18 13:40:08 +053015174 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070015175 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070015176 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053015177 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070015178 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070015179 GFP_ATOMIC);
15180 if (!skb)
15181 {
15182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15183 "LPHB timeout, NL buffer alloc fail");
15184 return;
15185 }
15186
Leo Changac3ba772013-10-07 09:47:04 -070015187 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070015188 {
15189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15190 "WLAN_HDD_TM_ATTR_CMD put fail");
15191 goto nla_put_failure;
15192 }
Leo Changac3ba772013-10-07 09:47:04 -070015193 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070015194 {
15195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15196 "WLAN_HDD_TM_ATTR_TYPE put fail");
15197 goto nla_put_failure;
15198 }
Leo Changac3ba772013-10-07 09:47:04 -070015199 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070015200 sizeof(tSirLPHBInd), lphbInd))
15201 {
15202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15203 "WLAN_HDD_TM_ATTR_DATA put fail");
15204 goto nla_put_failure;
15205 }
Leo Chang9056f462013-08-01 19:21:11 -070015206 cfg80211_testmode_event(skb, GFP_ATOMIC);
15207 return;
15208
15209nla_put_failure:
15210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15211 "NLA Put fail");
15212 kfree_skb(skb);
15213
15214 return;
15215}
15216#endif /* FEATURE_WLAN_LPHB */
15217
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015218static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070015219{
15220 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
15221 int err = 0;
15222#ifdef FEATURE_WLAN_LPHB
15223 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070015224 eHalStatus smeStatus;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015225 err = wlan_hdd_validate_context(pHddCtx);
15226 if (0 != err)
15227 {
15228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15229 "%s: HDD context is not valid", __func__);
15230 return err;
15231 }
Leo Chang9056f462013-08-01 19:21:11 -070015232#endif /* FEATURE_WLAN_LPHB */
15233
15234 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
15235 if (err)
15236 {
15237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15238 "%s Testmode INV ATTR", __func__);
15239 return err;
15240 }
15241
15242 if (!tb[WLAN_HDD_TM_ATTR_CMD])
15243 {
15244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15245 "%s Testmode INV CMD", __func__);
15246 return -EINVAL;
15247 }
15248
15249 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
15250 {
15251#ifdef FEATURE_WLAN_LPHB
15252 /* Low Power Heartbeat configuration request */
15253 case WLAN_HDD_TM_CMD_WLAN_HB:
15254 {
15255 int buf_len;
15256 void *buf;
15257 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080015258 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070015259
15260 if (!tb[WLAN_HDD_TM_ATTR_DATA])
15261 {
15262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15263 "%s Testmode INV DATA", __func__);
15264 return -EINVAL;
15265 }
15266
15267 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
15268 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080015269
15270 hb_params_temp =(tSirLPHBReq *)buf;
15271 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
15272 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
15273 return -EINVAL;
15274
Leo Chang9056f462013-08-01 19:21:11 -070015275 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
15276 if (NULL == hb_params)
15277 {
15278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15279 "%s Request Buffer Alloc Fail", __func__);
15280 return -EINVAL;
15281 }
15282
15283 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070015284 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
15285 hb_params,
15286 wlan_hdd_cfg80211_lphb_ind_handler);
15287 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070015288 {
Leo Changd9df8aa2013-09-26 13:32:26 -070015289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15290 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070015291 vos_mem_free(hb_params);
15292 }
Leo Chang9056f462013-08-01 19:21:11 -070015293 return 0;
15294 }
15295#endif /* FEATURE_WLAN_LPHB */
15296 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15298 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070015299 return -EOPNOTSUPP;
15300 }
15301
15302 return err;
15303}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015304
15305static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
15306{
15307 int ret;
15308
15309 vos_ssr_protect(__func__);
15310 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
15311 vos_ssr_unprotect(__func__);
15312
15313 return ret;
15314}
Leo Chang9056f462013-08-01 19:21:11 -070015315#endif /* CONFIG_NL80211_TESTMODE */
15316
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015317static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015318 struct net_device *dev,
15319 int idx, struct survey_info *survey)
15320{
15321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15322 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053015323 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015324 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053015325 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015326 v_S7_t snr,rssi;
15327 int status, i, j, filled = 0;
15328
15329 ENTER();
15330
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015331 if (NULL == pAdapter)
15332 {
15333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15334 "%s: HDD adapter is Null", __func__);
15335 return -ENODEV;
15336 }
15337
15338 if (NULL == wiphy)
15339 {
15340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15341 "%s: wiphy is Null", __func__);
15342 return -ENODEV;
15343 }
15344
15345 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15346 status = wlan_hdd_validate_context(pHddCtx);
15347
15348 if (0 != status)
15349 {
15350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15351 "%s: HDD context is not valid", __func__);
15352 return status;
15353 }
15354
Mihir Sheted9072e02013-08-21 17:02:29 +053015355 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15356
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015357 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053015358 0 != pAdapter->survey_idx ||
15359 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015360 {
15361 /* The survey dump ops when implemented completely is expected to
15362 * return a survey of all channels and the ops is called by the
15363 * kernel with incremental values of the argument 'idx' till it
15364 * returns -ENONET. But we can only support the survey for the
15365 * operating channel for now. survey_idx is used to track
15366 * that the ops is called only once and then return -ENONET for
15367 * the next iteration
15368 */
15369 pAdapter->survey_idx = 0;
15370 return -ENONET;
15371 }
15372
15373 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15374
15375 wlan_hdd_get_snr(pAdapter, &snr);
15376 wlan_hdd_get_rssi(pAdapter, &rssi);
15377
15378 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
15379 hdd_wlan_get_freq(channel, &freq);
15380
15381
15382 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
15383 {
15384 if (NULL == wiphy->bands[i])
15385 {
15386 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
15387 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
15388 continue;
15389 }
15390
15391 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
15392 {
15393 struct ieee80211_supported_band *band = wiphy->bands[i];
15394
15395 if (band->channels[j].center_freq == (v_U16_t)freq)
15396 {
15397 survey->channel = &band->channels[j];
15398 /* The Rx BDs contain SNR values in dB for the received frames
15399 * while the supplicant expects noise. So we calculate and
15400 * return the value of noise (dBm)
15401 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
15402 */
15403 survey->noise = rssi - snr;
15404 survey->filled = SURVEY_INFO_NOISE_DBM;
15405 filled = 1;
15406 }
15407 }
15408 }
15409
15410 if (filled)
15411 pAdapter->survey_idx = 1;
15412 else
15413 {
15414 pAdapter->survey_idx = 0;
15415 return -ENONET;
15416 }
15417
15418 return 0;
15419}
15420
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015421static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
15422 struct net_device *dev,
15423 int idx, struct survey_info *survey)
15424{
15425 int ret;
15426
15427 vos_ssr_protect(__func__);
15428 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
15429 vos_ssr_unprotect(__func__);
15430
15431 return ret;
15432}
15433
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015434/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015435 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015436 * this is called when cfg80211 driver resume
15437 * driver updates latest sched_scan scan result(if any) to cfg80211 database
15438 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015439int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015440{
15441 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15442 hdd_adapter_t *pAdapter;
15443 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15444 VOS_STATUS status = VOS_STATUS_SUCCESS;
15445
15446 ENTER();
15447
15448 if ( NULL == pHddCtx )
15449 {
15450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15451 "%s: HddCtx validation failed", __func__);
15452 return 0;
15453 }
15454
15455 if (pHddCtx->isLogpInProgress)
15456 {
15457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15458 "%s: LOGP in Progress. Ignore!!!", __func__);
15459 return 0;
15460 }
15461
Mihir Shete18156292014-03-11 15:38:30 +053015462 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015463 {
15464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15465 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15466 return 0;
15467 }
15468
15469 spin_lock(&pHddCtx->schedScan_lock);
15470 pHddCtx->isWiphySuspended = FALSE;
15471 if (TRUE != pHddCtx->isSchedScanUpdatePending)
15472 {
15473 spin_unlock(&pHddCtx->schedScan_lock);
15474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15475 "%s: Return resume is not due to PNO indication", __func__);
15476 return 0;
15477 }
15478 // Reset flag to avoid updatating cfg80211 data old results again
15479 pHddCtx->isSchedScanUpdatePending = FALSE;
15480 spin_unlock(&pHddCtx->schedScan_lock);
15481
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015482
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015483 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15484
15485 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15486 {
15487 pAdapter = pAdapterNode->pAdapter;
15488 if ( (NULL != pAdapter) &&
15489 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
15490 {
15491 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015492 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15494 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015495 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015496 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015497 {
15498 /* Acquire wakelock to handle the case where APP's tries to
15499 * suspend immediately after updating the scan results. Whis
15500 * results in app's is in suspended state and not able to
15501 * process the connect request to AP
15502 */
15503 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015504 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053015505 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015506
15507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15508 "%s : cfg80211 scan result database updated", __func__);
15509
15510 return 0;
15511
15512 }
15513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15514 pAdapterNode = pNext;
15515 }
15516
15517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15518 "%s: Failed to find Adapter", __func__);
15519 return 0;
15520}
15521
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015522int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
15523{
15524 int ret;
15525
15526 vos_ssr_protect(__func__);
15527 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
15528 vos_ssr_unprotect(__func__);
15529
15530 return ret;
15531}
15532
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015533/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015534 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015535 * this is called when cfg80211 driver suspends
15536 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015537int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015538 struct cfg80211_wowlan *wow)
15539{
15540 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015541 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015542
15543 ENTER();
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015544 ret = wlan_hdd_validate_context(pHddCtx);
15545 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015546 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15548 "%s: HDD context is not valid", __func__);
15549 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015550 }
15551
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015552
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015553 pHddCtx->isWiphySuspended = TRUE;
15554
15555 EXIT();
15556
15557 return 0;
15558}
15559
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053015560int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
15561 struct cfg80211_wowlan *wow)
15562{
15563 int ret;
15564
15565 vos_ssr_protect(__func__);
15566 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
15567 vos_ssr_unprotect(__func__);
15568
15569 return ret;
15570}
Jeff Johnson295189b2012-06-20 16:38:30 -070015571/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015572static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070015573{
15574 .add_virtual_intf = wlan_hdd_add_virtual_intf,
15575 .del_virtual_intf = wlan_hdd_del_virtual_intf,
15576 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
15577 .change_station = wlan_hdd_change_station,
15578#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
15579 .add_beacon = wlan_hdd_cfg80211_add_beacon,
15580 .del_beacon = wlan_hdd_cfg80211_del_beacon,
15581 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015582#else
15583 .start_ap = wlan_hdd_cfg80211_start_ap,
15584 .change_beacon = wlan_hdd_cfg80211_change_beacon,
15585 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070015586#endif
15587 .change_bss = wlan_hdd_cfg80211_change_bss,
15588 .add_key = wlan_hdd_cfg80211_add_key,
15589 .get_key = wlan_hdd_cfg80211_get_key,
15590 .del_key = wlan_hdd_cfg80211_del_key,
15591 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015592#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070015593 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015594#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015595 .scan = wlan_hdd_cfg80211_scan,
15596 .connect = wlan_hdd_cfg80211_connect,
15597 .disconnect = wlan_hdd_cfg80211_disconnect,
15598 .join_ibss = wlan_hdd_cfg80211_join_ibss,
15599 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
15600 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
15601 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
15602 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070015603 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
15604 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053015605 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070015606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15607 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
15608 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
15609 .set_txq_params = wlan_hdd_set_txq_params,
15610#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015611 .get_station = wlan_hdd_cfg80211_get_station,
15612 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
15613 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015614 .add_station = wlan_hdd_cfg80211_add_station,
15615#ifdef FEATURE_WLAN_LFR
15616 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
15617 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
15618 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
15619#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015620#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
15621 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
15622#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015623#ifdef FEATURE_WLAN_TDLS
15624 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
15625 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
15626#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015627#ifdef WLAN_FEATURE_GTK_OFFLOAD
15628 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
15629#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015630#ifdef FEATURE_WLAN_SCAN_PNO
15631 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
15632 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
15633#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015634 .resume = wlan_hdd_cfg80211_resume_wlan,
15635 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015636 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070015637#ifdef WLAN_NL80211_TESTMODE
15638 .testmode_cmd = wlan_hdd_cfg80211_testmode,
15639#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053015640 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070015641};
15642