blob: 4cb9e0d0fc73ae961e9dd98d923cb1dbb8e504ef [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#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530176static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700177{
178 WLAN_CIPHER_SUITE_WEP40,
179 WLAN_CIPHER_SUITE_WEP104,
180 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700182#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
183 WLAN_CIPHER_SUITE_KRK,
184 WLAN_CIPHER_SUITE_CCMP,
185#else
186 WLAN_CIPHER_SUITE_CCMP,
187#endif
188#ifdef FEATURE_WLAN_WAPI
189 WLAN_CIPHER_SUITE_SMS4,
190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700191#ifdef WLAN_FEATURE_11W
192 WLAN_CIPHER_SUITE_AES_CMAC,
193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700194};
195
196static inline int is_broadcast_ether_addr(const u8 *addr)
197{
198 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
199 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
200}
201
202static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530203{
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD2GHZCHAN(2412, 1, 0) ,
205 HDD2GHZCHAN(2417, 2, 0) ,
206 HDD2GHZCHAN(2422, 3, 0) ,
207 HDD2GHZCHAN(2427, 4, 0) ,
208 HDD2GHZCHAN(2432, 5, 0) ,
209 HDD2GHZCHAN(2437, 6, 0) ,
210 HDD2GHZCHAN(2442, 7, 0) ,
211 HDD2GHZCHAN(2447, 8, 0) ,
212 HDD2GHZCHAN(2452, 9, 0) ,
213 HDD2GHZCHAN(2457, 10, 0) ,
214 HDD2GHZCHAN(2462, 11, 0) ,
215 HDD2GHZCHAN(2467, 12, 0) ,
216 HDD2GHZCHAN(2472, 13, 0) ,
217 HDD2GHZCHAN(2484, 14, 0) ,
218};
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
221{
222 HDD2GHZCHAN(2412, 1, 0) ,
223 HDD2GHZCHAN(2437, 6, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225};
Jeff Johnson295189b2012-06-20 16:38:30 -0700226
227static struct ieee80211_channel hdd_channels_5_GHZ[] =
228{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700229 HDD5GHZCHAN(4920, 240, 0) ,
230 HDD5GHZCHAN(4940, 244, 0) ,
231 HDD5GHZCHAN(4960, 248, 0) ,
232 HDD5GHZCHAN(4980, 252, 0) ,
233 HDD5GHZCHAN(5040, 208, 0) ,
234 HDD5GHZCHAN(5060, 212, 0) ,
235 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 HDD5GHZCHAN(5180, 36, 0) ,
237 HDD5GHZCHAN(5200, 40, 0) ,
238 HDD5GHZCHAN(5220, 44, 0) ,
239 HDD5GHZCHAN(5240, 48, 0) ,
240 HDD5GHZCHAN(5260, 52, 0) ,
241 HDD5GHZCHAN(5280, 56, 0) ,
242 HDD5GHZCHAN(5300, 60, 0) ,
243 HDD5GHZCHAN(5320, 64, 0) ,
244 HDD5GHZCHAN(5500,100, 0) ,
245 HDD5GHZCHAN(5520,104, 0) ,
246 HDD5GHZCHAN(5540,108, 0) ,
247 HDD5GHZCHAN(5560,112, 0) ,
248 HDD5GHZCHAN(5580,116, 0) ,
249 HDD5GHZCHAN(5600,120, 0) ,
250 HDD5GHZCHAN(5620,124, 0) ,
251 HDD5GHZCHAN(5640,128, 0) ,
252 HDD5GHZCHAN(5660,132, 0) ,
253 HDD5GHZCHAN(5680,136, 0) ,
254 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800255#ifdef FEATURE_WLAN_CH144
256 HDD5GHZCHAN(5720,144, 0) ,
257#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 HDD5GHZCHAN(5745,149, 0) ,
259 HDD5GHZCHAN(5765,153, 0) ,
260 HDD5GHZCHAN(5785,157, 0) ,
261 HDD5GHZCHAN(5805,161, 0) ,
262 HDD5GHZCHAN(5825,165, 0) ,
263};
264
265static struct ieee80211_rate g_mode_rates[] =
266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530267 HDD_G_MODE_RATETAB(10, 0x1, 0),
268 HDD_G_MODE_RATETAB(20, 0x2, 0),
269 HDD_G_MODE_RATETAB(55, 0x4, 0),
270 HDD_G_MODE_RATETAB(110, 0x8, 0),
271 HDD_G_MODE_RATETAB(60, 0x10, 0),
272 HDD_G_MODE_RATETAB(90, 0x20, 0),
273 HDD_G_MODE_RATETAB(120, 0x40, 0),
274 HDD_G_MODE_RATETAB(180, 0x80, 0),
275 HDD_G_MODE_RATETAB(240, 0x100, 0),
276 HDD_G_MODE_RATETAB(360, 0x200, 0),
277 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530279};
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281static struct ieee80211_rate a_mode_rates[] =
282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283 HDD_G_MODE_RATETAB(60, 0x10, 0),
284 HDD_G_MODE_RATETAB(90, 0x20, 0),
285 HDD_G_MODE_RATETAB(120, 0x40, 0),
286 HDD_G_MODE_RATETAB(180, 0x80, 0),
287 HDD_G_MODE_RATETAB(240, 0x100, 0),
288 HDD_G_MODE_RATETAB(360, 0x200, 0),
289 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 HDD_G_MODE_RATETAB(540, 0x800, 0),
291};
292
293static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
294{
295 .channels = hdd_channels_2_4_GHZ,
296 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
297 .band = IEEE80211_BAND_2GHZ,
298 .bitrates = g_mode_rates,
299 .n_bitrates = g_mode_rates_size,
300 .ht_cap.ht_supported = 1,
301 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
302 | IEEE80211_HT_CAP_GRN_FLD
303 | IEEE80211_HT_CAP_DSSSCCK40
304 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
305 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
306 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
307 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
308 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
309 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
310};
311
Jeff Johnson295189b2012-06-20 16:38:30 -0700312static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
313{
314 .channels = hdd_social_channels_2_4_GHZ,
315 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
316 .band = IEEE80211_BAND_2GHZ,
317 .bitrates = g_mode_rates,
318 .n_bitrates = g_mode_rates_size,
319 .ht_cap.ht_supported = 1,
320 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
321 | IEEE80211_HT_CAP_GRN_FLD
322 | IEEE80211_HT_CAP_DSSSCCK40
323 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
324 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
325 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
326 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
327 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
328 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
329};
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
331static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
332{
333 .channels = hdd_channels_5_GHZ,
334 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
335 .band = IEEE80211_BAND_5GHZ,
336 .bitrates = a_mode_rates,
337 .n_bitrates = a_mode_rates_size,
338 .ht_cap.ht_supported = 1,
339 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
340 | IEEE80211_HT_CAP_GRN_FLD
341 | IEEE80211_HT_CAP_DSSSCCK40
342 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
343 | IEEE80211_HT_CAP_SGI_40
344 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
345 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
346 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
347 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
348 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
349 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
350};
351
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530352/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 TX/RX direction for each kind of interface */
354static const struct ieee80211_txrx_stypes
355wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
356 [NL80211_IFTYPE_STATION] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ACTION) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ),
360 },
361 [NL80211_IFTYPE_AP] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_PROBE_REQ) |
366 BIT(SIR_MAC_MGMT_DISASSOC) |
367 BIT(SIR_MAC_MGMT_AUTH) |
368 BIT(SIR_MAC_MGMT_DEAUTH) |
369 BIT(SIR_MAC_MGMT_ACTION),
370 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 [NL80211_IFTYPE_ADHOC] = {
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 [NL80211_IFTYPE_P2P_CLIENT] = {
382 .tx = 0xffff,
383 .rx = BIT(SIR_MAC_MGMT_ACTION) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ),
385 },
386 [NL80211_IFTYPE_P2P_GO] = {
387 /* This is also same as for SoftAP */
388 .tx = 0xffff,
389 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
391 BIT(SIR_MAC_MGMT_PROBE_REQ) |
392 BIT(SIR_MAC_MGMT_DISASSOC) |
393 BIT(SIR_MAC_MGMT_AUTH) |
394 BIT(SIR_MAC_MGMT_DEAUTH) |
395 BIT(SIR_MAC_MGMT_ACTION),
396 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700397};
398
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400static const struct ieee80211_iface_limit
401wlan_hdd_iface_limit[] = {
402 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /* max = 3 ; Our driver create two interfaces during driver init
404 * wlan0 and p2p0 interfaces. p2p0 is considered as station
405 * interface until a group is formed. In JB architecture, once the
406 * group is formed, interface type of p2p0 is changed to P2P GO or
407 * Client.
408 * When supplicant remove the group, it first issue a set interface
409 * cmd to change the mode back to Station. In JB this works fine as
410 * we advertize two station type interface during driver init.
411 * Some vendors create separate interface for P2P GO/Client,
412 * after group formation(Third one). But while group remove
413 * supplicant first tries to change the mode(3rd interface) to STATION
414 * But as we advertized only two sta type interfaces nl80211 was
415 * returning error for the third one which was leading to failure in
416 * delete interface. Ideally while removing the group, supplicant
417 * should not try to change the 3rd interface mode to Station type.
418 * Till we get a fix in wpa_supplicant, we advertize max STA
419 * interface type to 3
420 */
421 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422 .types = BIT(NL80211_IFTYPE_STATION),
423 },
424 {
425 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700426 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 },
428 {
429 .max = 1,
430 .types = BIT(NL80211_IFTYPE_P2P_GO) |
431 BIT(NL80211_IFTYPE_P2P_CLIENT),
432 },
433};
434
435/* By default, only single channel concurrency is allowed */
436static struct ieee80211_iface_combination
437wlan_hdd_iface_combination = {
438 .limits = wlan_hdd_iface_limit,
439 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800440 /*
441 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
442 * and p2p0 interfaces during driver init
443 * Some vendors create separate interface for P2P operations.
444 * wlan0: STA interface
445 * p2p0: P2P Device interface, action frames goes
446 * through this interface.
447 * p2p-xx: P2P interface, After GO negotiation this interface is
448 * created for p2p operations(GO/CLIENT interface).
449 */
450 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800451 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
452 .beacon_int_infra_match = false,
453};
454#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456static struct cfg80211_ops wlan_hdd_cfg80211_ops;
457
458/* Data rate 100KBPS based on IE Index */
459struct index_data_rate_type
460{
461 v_U8_t beacon_rate_index;
462 v_U16_t supported_rate[4];
463};
464
465/* 11B, 11G Rate table include Basic rate and Extended rate
466 The IDX field is the rate index
467 The HI field is the rate when RSSI is strong or being ignored
468 (in this case we report actual rate)
469 The MID field is the rate when RSSI is moderate
470 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
471 The LO field is the rate when RSSI is low
472 (in this case we don't report rates, actual current rate used)
473 */
474static const struct
475{
476 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700478} supported_data_rate[] =
479{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480/* IDX HI HM LM LO (RSSI-based index */
481 {2, { 10, 10, 10, 0}},
482 {4, { 20, 20, 10, 0}},
483 {11, { 55, 20, 10, 0}},
484 {12, { 60, 55, 20, 0}},
485 {18, { 90, 55, 20, 0}},
486 {22, {110, 55, 20, 0}},
487 {24, {120, 90, 60, 0}},
488 {36, {180, 120, 60, 0}},
489 {44, {220, 180, 60, 0}},
490 {48, {240, 180, 90, 0}},
491 {66, {330, 180, 90, 0}},
492 {72, {360, 240, 90, 0}},
493 {96, {480, 240, 120, 0}},
494 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700495};
496
497/* MCS Based rate table */
498static struct index_data_rate_type supported_mcs_rate[] =
499{
500/* MCS L20 L40 S20 S40 */
501 {0, {65, 135, 72, 150}},
502 {1, {130, 270, 144, 300}},
503 {2, {195, 405, 217, 450}},
504 {3, {260, 540, 289, 600}},
505 {4, {390, 810, 433, 900}},
506 {5, {520, 1080, 578, 1200}},
507 {6, {585, 1215, 650, 1350}},
508 {7, {650, 1350, 722, 1500}}
509};
510
Leo Chang6f8870f2013-03-26 18:11:36 -0700511#ifdef WLAN_FEATURE_11AC
512
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530513#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700514
515struct index_vht_data_rate_type
516{
517 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518 v_U16_t supported_VHT80_rate[2];
519 v_U16_t supported_VHT40_rate[2];
520 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700521};
522
523typedef enum
524{
525 DATA_RATE_11AC_MAX_MCS_7,
526 DATA_RATE_11AC_MAX_MCS_8,
527 DATA_RATE_11AC_MAX_MCS_9,
528 DATA_RATE_11AC_MAX_MCS_NA
529} eDataRate11ACMaxMcs;
530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530531/* SSID broadcast type */
532typedef enum eSSIDBcastType
533{
534 eBCAST_UNKNOWN = 0,
535 eBCAST_NORMAL = 1,
536 eBCAST_HIDDEN = 2,
537} tSSIDBcastType;
538
Leo Chang6f8870f2013-03-26 18:11:36 -0700539/* MCS Based VHT rate table */
540static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
541{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542/* MCS L80 S80 L40 S40 L20 S40*/
543 {0, {293, 325}, {135, 150}, {65, 72}},
544 {1, {585, 650}, {270, 300}, {130, 144}},
545 {2, {878, 975}, {405, 450}, {195, 217}},
546 {3, {1170, 1300}, {540, 600}, {260, 289}},
547 {4, {1755, 1950}, {810, 900}, {390, 433}},
548 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
549 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
550 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
551 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
552 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700553};
554#endif /* WLAN_FEATURE_11AC */
555
c_hpothu79aab322014-07-14 21:11:01 +0530556/*array index points to MCS and array value points respective rssi*/
557static int rssiMcsTbl[][10] =
558{
559/*MCS 0 1 2 3 4 5 6 7 8 9*/
560 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
561 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
562 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
563};
564
Jeff Johnson295189b2012-06-20 16:38:30 -0700565extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530566#ifdef FEATURE_WLAN_SCAN_PNO
567static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
626 NULL,
627#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648/*
649 * FUNCTION: __wlan_hdd_cfg80211_nan_request
650 * This is called when wlan driver needs to send vendor specific
651 * nan request event.
652 */
653static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
654 struct wireless_dev *wdev,
655 const void *data, int data_len)
656{
657 tNanRequestReq nan_req;
658 VOS_STATUS status;
659 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530660 struct net_device *dev = wdev->netdev;
661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
662 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
664
665 if (0 == data_len)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, length = 0"));
669 return ret_val;
670 }
671
672 if (NULL == data)
673 {
674 hddLog(VOS_TRACE_LEVEL_ERROR,
675 FL("NAN - Invalid Request, data is NULL"));
676 return ret_val;
677 }
678
679 status = wlan_hdd_validate_context(pHddCtx);
680 if (0 != status)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("HDD context is not valid"));
684 return -EINVAL;
685 }
686
687 hddLog(LOG1, FL("Received NAN command"));
688 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
689 (tANI_U8 *)data, data_len);
690
691 /* check the NAN Capability */
692 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR,
695 FL("NAN is not supported by Firmware"));
696 return -EINVAL;
697 }
698
699 nan_req.request_data_len = data_len;
700 nan_req.request_data = data;
701
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530702 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530703 if (VOS_STATUS_SUCCESS == status)
704 {
705 ret_val = 0;
706 }
707 return ret_val;
708}
709
710/*
711 * FUNCTION: wlan_hdd_cfg80211_nan_request
712 * Wrapper to protect the nan vendor command from ssr
713 */
714static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
715 struct wireless_dev *wdev,
716 const void *data, int data_len)
717{
718 int ret;
719
720 vos_ssr_protect(__func__);
721 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
722 vos_ssr_unprotect(__func__);
723
724 return ret;
725}
726
727/*
728 * FUNCTION: wlan_hdd_cfg80211_nan_callback
729 * This is a callback function and it gets called
730 * when we need to report nan response event to
731 * upper layers.
732 */
733static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
734{
735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
736 struct sk_buff *vendor_event;
737 int status;
738 tSirNanEvent *data;
739
740 ENTER();
741 if (NULL == msg)
742 {
743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
744 FL(" msg received here is null"));
745 return;
746 }
747 data = msg;
748
749 status = wlan_hdd_validate_context(pHddCtx);
750
751 if (0 != status)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("HDD context is not valid"));
755 return;
756 }
757
758 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
760 NULL,
761#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530762 data->event_data_len +
763 NLMSG_HDRLEN,
764 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
765 GFP_KERNEL);
766
767 if (!vendor_event)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("cfg80211_vendor_event_alloc failed"));
771 return;
772 }
773 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
774 data->event_data_len, data->event_data))
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
778 kfree_skb(vendor_event);
779 return;
780 }
781 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
782 EXIT();
783}
784
785/*
786 * FUNCTION: wlan_hdd_cfg80211_nan_init
787 * This function is called to register the callback to sme layer
788 */
789inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
790{
791 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
792}
793
794
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795#ifdef WLAN_FEATURE_LINK_LAYER_STATS
796
797static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
798 struct sk_buff *vendor_event)
799{
800 if (nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
802 stats->rate.preamble) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
805 stats->rate.nss) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
808 stats->rate.bw) ||
809 nla_put_u8(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
811 stats->rate.rateMcsIdx) ||
812 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
813 stats->rate.bitrate ) ||
814 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
815 stats->txMpdu ) ||
816 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
817 stats->rxMpdu ) ||
818 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
819 stats->mpduLost ) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
821 stats->retries) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
824 stats->retriesShort ) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
827 stats->retriesLong))
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,
830 FL("QCA_WLAN_VENDOR_ATTR put fail"));
831 return FALSE;
832 }
833 return TRUE;
834}
835
836static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
837 struct sk_buff *vendor_event)
838{
839 u32 i = 0;
840 struct nlattr *rateInfo;
841 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
842 stats->type) ||
843 nla_put(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
845 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
848 stats->capabilities) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
851 stats->numRate))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 goto error;
856 }
857
858 rateInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rateInfo)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862 for (i = 0; i < stats->numRate; i++)
863 {
864 struct nlattr *rates;
865 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
866 stats->rateStats +
867 (i * sizeof(tSirWifiRateStat)));
868 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530869 if(!rates)
870 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530871
872 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
875 FL("QCA_WLAN_VENDOR_ATTR put fail"));
876 return FALSE;
877 }
878 nla_nest_end(vendor_event, rates);
879 }
880 nla_nest_end(vendor_event, rateInfo);
881
882 return TRUE;
883error:
884 return FALSE;
885}
886
887static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
888 struct sk_buff *vendor_event)
889{
890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
891 stats->ac ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
894 stats->txMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
897 stats->rxMpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
900 stats->txMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
903 stats->rxMcast ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
906 stats->rxAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
909 stats->txAmpdu ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
912 stats->mpduLost )||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
915 stats->retries ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
918 stats->retriesShort ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
921 stats->retriesLong ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
924 stats->contentionTimeMin ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
927 stats->contentionTimeMax ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
930 stats->contentionTimeAvg ) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
933 stats->contentionNumSamples ))
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR,
936 FL("QCA_WLAN_VENDOR_ATTR put fail") );
937 return FALSE;
938 }
939 return TRUE;
940}
941
942static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
943 struct sk_buff *vendor_event)
944{
Dino Myclec8f3f332014-07-21 16:48:27 +0530945 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
949 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
952 stats->state ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
955 stats->roaming ) ||
956 nla_put_u32(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
958 stats->capabilities ) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
961 strlen(stats->ssid), stats->ssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
964 WNI_CFG_BSSID_LEN, stats->bssid) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
968 nla_put(vendor_event,
969 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
970 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
971 )
972 {
973 hddLog(VOS_TRACE_LEVEL_ERROR,
974 FL("QCA_WLAN_VENDOR_ATTR put fail") );
975 return FALSE;
976 }
977 return TRUE;
978}
979
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
981 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530982 struct sk_buff *vendor_event)
983{
984 int i = 0;
985 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
987 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530988 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 if (FALSE == put_wifi_interface_info(
991 &pWifiIfaceStat->info,
992 vendor_event))
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR,
995 FL("QCA_WLAN_VENDOR_ATTR put fail") );
996 return FALSE;
997
998 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530999 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1000 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1001 if (NULL == pWifiIfaceStatTL)
1002 {
1003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1004 return FALSE;
1005 }
1006
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301007 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1011
1012 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301016
1017 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1018 {
1019 if (VOS_STATUS_SUCCESS ==
1020 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1021 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1022 {
1023 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1024 * obtained from TL structure
1025 */
1026
1027 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1028 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048
Srinivas Dasari98947432014-11-07 19:41:24 +05301049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1050 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1052 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1054 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1056 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301057 }
1058 else
1059 {
1060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1061 }
1062
Dino Mycle3b9536d2014-07-09 22:05:24 +05301063 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1065 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1070 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1071 }
1072 else
1073 {
1074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1075 }
1076
1077
Sunil Duttc69bccb2014-05-26 21:30:20 +05301078
1079 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1082 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1084 pWifiIfaceStat->beaconRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1087 pWifiIfaceStat->mgmtRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1090 pWifiIfaceStat->mgmtActionRx) ||
1091 nla_put_u32(vendor_event,
1092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1093 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1096 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1099 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1102 pWifiIfaceStat->rssiAck))
1103 {
1104 hddLog(VOS_TRACE_LEVEL_ERROR,
1105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
1110 wmmInfo = nla_nest_start(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301112 if(!wmmInfo)
1113 {
1114 vos_mem_free(pWifiIfaceStatTL);
1115 return FALSE;
1116 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301117 for (i = 0; i < WIFI_AC_MAX; i++)
1118 {
1119 struct nlattr *wmmStats;
1120 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301121 if(!wmmStats)
1122 {
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301126 if (FALSE == put_wifi_wmm_ac_stat(
1127 &pWifiIfaceStat->AccessclassStats[i],
1128 vendor_event))
1129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR,
1131 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301132 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301133 return FALSE;
1134 }
1135
1136 nla_nest_end(vendor_event, wmmStats);
1137 }
1138 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301139 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301140 return TRUE;
1141}
1142
1143static tSirWifiInterfaceMode
1144 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1145{
1146 switch (deviceMode)
1147 {
1148 case WLAN_HDD_INFRA_STATION:
1149 return WIFI_INTERFACE_STA;
1150 case WLAN_HDD_SOFTAP:
1151 return WIFI_INTERFACE_SOFTAP;
1152 case WLAN_HDD_P2P_CLIENT:
1153 return WIFI_INTERFACE_P2P_CLIENT;
1154 case WLAN_HDD_P2P_GO:
1155 return WIFI_INTERFACE_P2P_GO;
1156 case WLAN_HDD_IBSS:
1157 return WIFI_INTERFACE_IBSS;
1158 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301159 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 }
1161}
1162
1163static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1164 tpSirWifiInterfaceInfo pInfo)
1165{
1166 v_U8_t *staMac = NULL;
1167 hdd_station_ctx_t *pHddStaCtx;
1168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1169 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1170
1171 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1172
1173 vos_mem_copy(pInfo->macAddr,
1174 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1175
1176 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1178 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1179 {
1180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1181 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1182 {
1183 pInfo->state = WIFI_DISCONNECTED;
1184 }
1185 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1186 {
1187 hddLog(VOS_TRACE_LEVEL_ERROR,
1188 "%s: Session ID %d, Connection is in progress", __func__,
1189 pAdapter->sessionId);
1190 pInfo->state = WIFI_ASSOCIATING;
1191 }
1192 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1193 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1194 {
1195 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: client " MAC_ADDRESS_STR
1198 " is in the middle of WPS/EAPOL exchange.", __func__,
1199 MAC_ADDR_ARRAY(staMac));
1200 pInfo->state = WIFI_AUTHENTICATING;
1201 }
1202 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_ASSOCIATED;
1205 vos_mem_copy(pInfo->bssid,
1206 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1207 vos_mem_copy(pInfo->ssid,
1208 pHddStaCtx->conn_info.SSID.SSID.ssId,
1209 pHddStaCtx->conn_info.SSID.SSID.length);
1210 //NULL Terminate the string.
1211 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1212 }
1213 }
1214 vos_mem_copy(pInfo->countryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 vos_mem_copy(pInfo->apCountryStr,
1218 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1219
1220 return TRUE;
1221}
1222
1223/*
1224 * hdd_link_layer_process_peer_stats () - This function is called after
1225 * receiving Link Layer Peer statistics from FW.This function converts
1226 * the firmware data to the NL data and sends the same to the kernel/upper
1227 * layers.
1228 */
1229static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1230 v_VOID_t *pData)
1231{
1232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 tpSirWifiPeerStat pWifiPeerStat;
1234 tpSirWifiPeerInfo pWifiPeerInfo;
1235 struct nlattr *peerInfo;
1236 struct sk_buff *vendor_event;
1237 int status, i;
1238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301239 ENTER();
1240
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 status = wlan_hdd_validate_context(pHddCtx);
1242 if (0 != status)
1243 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244 return;
1245 }
1246
1247 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "LL_STATS_PEER_ALL : numPeers %u",
1251 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301252 /*
1253 * Allocate a size of 4096 for the peer stats comprising
1254 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1255 * sizeof (tSirWifiRateStat).Each field is put with an
1256 * NL attribute.The size of 4096 is considered assuming
1257 * that number of rates shall not exceed beyond 50 with
1258 * the sizeof (tSirWifiRateStat) being 32.
1259 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301260 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1261 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 if (!vendor_event)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301265 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 __func__);
1267 return;
1268 }
1269 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1271 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1272 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1274 pWifiPeerStat->numPeers))
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1278 kfree_skb(vendor_event);
1279 return;
1280 }
1281
1282 peerInfo = nla_nest_start(vendor_event,
1283 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301284 if(!peerInfo)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1288 __func__);
1289 kfree_skb(vendor_event);
1290 return;
1291 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301292
1293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1294 pWifiPeerStat->peerInfo);
1295
1296 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1297 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301299 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301301 if(!peers)
1302 {
1303 hddLog(VOS_TRACE_LEVEL_ERROR,
1304 "%s: peer stats put fail",
1305 __func__);
1306 kfree_skb(vendor_event);
1307 return;
1308 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 if (FALSE == put_wifi_peer_info(
1310 pWifiPeerInfo, vendor_event))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: put_wifi_peer_info put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo +
1320 (i * sizeof(tSirWifiPeerInfo)) +
1321 (numRate * sizeof (tSirWifiRateStat)));
1322 nla_nest_end(vendor_event, peers);
1323 }
1324 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301325 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301326 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327}
1328
1329/*
1330 * hdd_link_layer_process_iface_stats () - This function is called after
1331 * receiving Link Layer Interface statistics from FW.This function converts
1332 * the firmware data to the NL data and sends the same to the kernel/upper
1333 * layers.
1334 */
1335static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1336 v_VOID_t *pData)
1337{
1338 tpSirWifiIfaceStat pWifiIfaceStat;
1339 struct sk_buff *vendor_event;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 int status;
1342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301343 ENTER();
1344
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 status = wlan_hdd_validate_context(pHddCtx);
1346 if (0 != status)
1347 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348 return;
1349 }
1350 /*
1351 * Allocate a size of 4096 for the interface stats comprising
1352 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1353 * assuming that all these fit with in the limit.Please take
1354 * a call on the limit based on the data requirements on
1355 * interface statistics.
1356 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301357 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1358 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 if (!vendor_event)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301362 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 return;
1364 }
1365
1366 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1367
Dino Mycle3b9536d2014-07-09 22:05:24 +05301368
1369 if (FALSE == hdd_get_interface_info( pAdapter,
1370 &pWifiIfaceStat->info))
1371 {
1372 hddLog(VOS_TRACE_LEVEL_ERROR,
1373 FL("hdd_get_interface_info get fail") );
1374 kfree_skb(vendor_event);
1375 return;
1376 }
1377
1378 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1379 vendor_event))
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 FL("put_wifi_iface_stats fail") );
1383 kfree_skb(vendor_event);
1384 return;
1385 }
1386
Sunil Duttc69bccb2014-05-26 21:30:20 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
1388 "WMI_LINK_STATS_IFACE Data");
1389
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301390 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 if (!vendor_event)
1448 {
1449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 return;
1452 }
1453
1454 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1457 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
Sunil Duttc69bccb2014-05-26 21:30:20 +05301515 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301516 if(!chInfo)
1517 {
1518 hddLog(VOS_TRACE_LEVEL_ERROR,
1519 "%s: failed to put chInfo",
1520 __func__);
1521 kfree_skb(vendor_event);
1522 return;
1523 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524
1525 if (nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1527 pWifiChannelStats->channel.width) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1530 pWifiChannelStats->channel.centerFreq) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1533 pWifiChannelStats->channel.centerFreq0) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1536 pWifiChannelStats->channel.centerFreq1) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1539 pWifiChannelStats->onTime) ||
1540 nla_put_u32(vendor_event,
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1542 pWifiChannelStats->ccaBusyTime))
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 FL("cfg80211_vendor_event_alloc failed") );
1546 kfree_skb(vendor_event);
1547 return ;
1548 }
1549 nla_nest_end(vendor_event, chInfo);
1550 }
1551 nla_nest_end(vendor_event, chList);
1552
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301553 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301554
1555 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 return;
1557}
1558
1559/*
1560 * hdd_link_layer_stats_ind_callback () - This function is called after
1561 * receiving Link Layer indications from FW.This callback converts the firmware
1562 * data to the NL data and send the same to the kernel/upper layers.
1563 */
1564static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1565 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301566 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567{
Dino Mycled3d50022014-07-07 12:58:25 +05301568 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1569 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301570 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301571 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 int status;
1573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301576 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 if (0 != status)
1578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580 }
1581
Dino Mycled3d50022014-07-07 12:58:25 +05301582 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1583 if (NULL == pAdapter)
1584 {
1585 hddLog(VOS_TRACE_LEVEL_ERROR,
1586 FL(" MAC address %pM does not exist with host"),
1587 macAddr);
1588 return;
1589 }
1590
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "%s: Interface: %s LLStats indType: %d", __func__,
1593 pAdapter->dev->name, indType);
1594
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 switch (indType)
1596 {
1597 case SIR_HAL_LL_STATS_RESULTS_RSP:
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301600 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1601 "respId = %u, moreResultToFollow = %u",
1602 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1603 macAddr, linkLayerStatsResults->respId,
1604 linkLayerStatsResults->moreResultToFollow);
1605
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 spin_lock(&hdd_context_lock);
1607 context = &pHddCtx->ll_stats_context;
1608 /* validate response received from target */
1609 if ((context->request_id != linkLayerStatsResults->respId) ||
1610 !(context->request_bitmap & linkLayerStatsResults->paramId))
1611 {
1612 spin_unlock(&hdd_context_lock);
1613 hddLog(LOGE,
1614 FL("Error : Request id %d response id %d request bitmap 0x%x"
1615 "response bitmap 0x%x"),
1616 context->request_id, linkLayerStatsResults->respId,
1617 context->request_bitmap, linkLayerStatsResults->paramId);
1618 return;
1619 }
1620 spin_unlock(&hdd_context_lock);
1621
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1623 {
1624 hdd_link_layer_process_radio_stats(pAdapter,
1625 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1628 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 }
1630 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1631 {
1632 hdd_link_layer_process_iface_stats(pAdapter,
1633 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301634 spin_lock(&hdd_context_lock);
1635 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1636 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 }
1638 else if ( linkLayerStatsResults->paramId &
1639 WMI_LINK_STATS_ALL_PEER )
1640 {
1641 hdd_link_layer_process_peer_stats(pAdapter,
1642 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301643 spin_lock(&hdd_context_lock);
1644 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1645 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646 } /* WMI_LINK_STATS_ALL_PEER */
1647 else
1648 {
1649 hddLog(VOS_TRACE_LEVEL_ERROR,
1650 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1651 }
1652
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301653 spin_lock(&hdd_context_lock);
1654 /* complete response event if all requests are completed */
1655 if (0 == context->request_bitmap)
1656 complete(&context->response_event);
1657 spin_unlock(&hdd_context_lock);
1658
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 break;
1660 }
1661 default:
1662 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1663 break;
1664 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301665
1666 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 return;
1668}
1669
1670const struct
1671nla_policy
1672qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1673{
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1675 { .type = NLA_U32 },
1676 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1677 { .type = NLA_U32 },
1678};
1679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301680static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1681 struct wireless_dev *wdev,
1682 const void *data,
1683 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684{
1685 int status;
1686 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 struct net_device *dev = wdev->netdev;
1689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301692 ENTER();
1693
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 status = wlan_hdd_validate_context(pHddCtx);
1695 if (0 != status)
1696 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return -EINVAL;
1698 }
1699
1700 if (NULL == pAdapter)
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("HDD adapter is Null"));
1704 return -ENODEV;
1705 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 /* check the LLStats Capability */
1707 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1708 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("Link Layer Statistics not supported by Firmware"));
1712 return -EINVAL;
1713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1716 (struct nlattr *)data,
1717 data_len, qca_wlan_vendor_ll_set_policy))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1720 return -EINVAL;
1721 }
1722 if (!tb_vendor
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1726 return -EINVAL;
1727 }
1728 if (!tb_vendor[
1729 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1740
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301742 nla_get_u32(
1743 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1744
Dino Mycled3d50022014-07-07 12:58:25 +05301745 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1746 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747
1748
1749 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301750 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1751 "Statistics Gathering = %d ",
1752 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1753 linkLayerStatsSetReq.mpduSizeThreshold,
1754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1770 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771 return -EINVAL;
1772 }
1773
1774 pAdapter->isLinkLayerStatsSet = 1;
1775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301776 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 return 0;
1778}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301779static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1780 struct wireless_dev *wdev,
1781 const void *data,
1782 int data_len)
1783{
1784 int ret = 0;
1785
1786 vos_ssr_protect(__func__);
1787 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1788 vos_ssr_unprotect(__func__);
1789
1790 return ret;
1791}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792
1793const struct
1794nla_policy
1795qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1796{
1797 /* Unsigned 32bit value provided by the caller issuing the GET stats
1798 * command. When reporting
1799 * the stats results, the driver uses the same value to indicate
1800 * which GET request the results
1801 * correspond to.
1802 */
1803 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1804
1805 /* Unsigned 32bit value . bit mask to identify what statistics are
1806 requested for retrieval */
1807 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1808};
1809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301810static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1811 struct wireless_dev *wdev,
1812 const void *data,
1813 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301815 unsigned long rc;
1816 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 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);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 int status;
1824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301825 ENTER();
1826
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 status = wlan_hdd_validate_context(pHddCtx);
1828 if (0 != status)
1829 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 return -EINVAL ;
1831 }
1832
1833 if (NULL == pAdapter)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL,
1836 "%s: HDD adapter is Null", __func__);
1837 return -ENODEV;
1838 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301839
1840 if (pHddStaCtx == NULL)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,
1843 "%s: HddStaCtx is Null", __func__);
1844 return -ENODEV;
1845 }
1846
Dino Mycledf0a5d92014-07-04 09:41:55 +05301847 /* check the LLStats Capability */
1848 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1849 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1850 {
1851 hddLog(VOS_TRACE_LEVEL_ERROR,
1852 FL("Link Layer Statistics not supported by Firmware"));
1853 return -EINVAL;
1854 }
1855
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856
1857 if (!pAdapter->isLinkLayerStatsSet)
1858 {
1859 hddLog(VOS_TRACE_LEVEL_FATAL,
1860 "%s: isLinkLayerStatsSet : %d",
1861 __func__, pAdapter->isLinkLayerStatsSet);
1862 return -EINVAL;
1863 }
1864
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "%s: Roaming in progress, so unable to proceed this request", __func__);
1869 return -EBUSY;
1870 }
1871
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1873 (struct nlattr *)data,
1874 data_len, qca_wlan_vendor_ll_get_policy))
1875 {
1876 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1877 return -EINVAL;
1878 }
1879
1880 if (!tb_vendor
1881 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1882 {
1883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1884 return -EINVAL;
1885 }
1886
1887 if (!tb_vendor
1888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1891 return -EINVAL;
1892 }
1893
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1901
Dino Mycled3d50022014-07-07 12:58:25 +05301902 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1903 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904
1905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301906 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1907 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301910 spin_lock(&hdd_context_lock);
1911 context = &pHddCtx->ll_stats_context;
1912 context->request_id = linkLayerStatsGetReq.reqId;
1913 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1914 INIT_COMPLETION(context->response_event);
1915 spin_unlock(&hdd_context_lock);
1916
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1921 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 return -EINVAL;
1923 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301924
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301925 rc = wait_for_completion_timeout(&context->response_event,
1926 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1927 if (!rc)
1928 {
1929 hddLog(LOGE,
1930 FL("Target response timed out request id %d request bitmap 0x%x"),
1931 context->request_id, context->request_bitmap);
1932 return -ETIMEDOUT;
1933 }
1934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301935 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 return 0;
1937}
1938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301939static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1940 struct wireless_dev *wdev,
1941 const void *data,
1942 int data_len)
1943{
1944 int ret = 0;
1945
1946 vos_ssr_protect(__func__);
1947 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953const struct
1954nla_policy
1955qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1956{
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1961};
1962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301963static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1964 struct wireless_dev *wdev,
1965 const void *data,
1966 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301967{
1968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1969 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301970 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 struct net_device *dev = wdev->netdev;
1972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1973 u32 statsClearReqMask;
1974 u8 stopReq;
1975 int status;
1976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301977 ENTER();
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 status = wlan_hdd_validate_context(pHddCtx);
1980 if (0 != status)
1981 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 return -EINVAL;
1983 }
1984
1985 if (NULL == pAdapter)
1986 {
1987 hddLog(VOS_TRACE_LEVEL_FATAL,
1988 "%s: HDD adapter is Null", __func__);
1989 return -ENODEV;
1990 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 /* check the LLStats Capability */
1992 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1993 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("Enable LLStats Capability"));
1997 return -EINVAL;
1998 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999
2000 if (!pAdapter->isLinkLayerStatsSet)
2001 {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,
2003 "%s: isLinkLayerStatsSet : %d",
2004 __func__, pAdapter->isLinkLayerStatsSet);
2005 return -EINVAL;
2006 }
2007
2008 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2009 (struct nlattr *)data,
2010 data_len, qca_wlan_vendor_ll_clr_policy))
2011 {
2012 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2013 return -EINVAL;
2014 }
2015
2016 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2017
2018 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2019 {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2021 return -EINVAL;
2022
2023 }
2024
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycledf0a5d92014-07-04 09:41:55 +05302026 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 nla_get_u32(
2028 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2029
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 nla_get_u8(
2032 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2033
2034 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
Dino Mycled3d50022014-07-07 12:58:25 +05302037 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2038 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302041 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2042 "statsClearReqMask = 0x%X, stopReq = %d",
2043 linkLayerStatsClearReq.reqId,
2044 linkLayerStatsClearReq.macAddr,
2045 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047
2048 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 {
2051 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302052 hdd_station_ctx_t *pHddStaCtx;
2053
2054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2055 if (VOS_STATUS_SUCCESS !=
2056 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2057 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2060 "WLANTL_ClearInterfaceStats Failed", __func__);
2061 return -EINVAL;
2062 }
2063 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2064 (statsClearReqMask & WIFI_STATS_IFACE)) {
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2069 }
2070
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2072 2 * sizeof(u32) +
2073 NLMSG_HDRLEN);
2074
2075 if (temp_skbuff != NULL)
2076 {
2077
2078 if (nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2080 statsClearReqMask) ||
2081 nla_put_u32(temp_skbuff,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2083 stopReq))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2086 kfree_skb(temp_skbuff);
2087 return -EINVAL;
2088 }
2089 /* If the ask is to stop the stats collection as part of clear
2090 * (stopReq = 1) , ensure that no further requests of get
2091 * go to the firmware by having isLinkLayerStatsSet set to 0.
2092 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 * case the firmware is just asked to clear the statistics.
2095 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302096 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 pAdapter->isLinkLayerStatsSet = 0;
2098 return cfg80211_vendor_cmd_reply(temp_skbuff);
2099 }
2100 return -ENOMEM;
2101 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102
2103 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return -EINVAL;
2105}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302106static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2107 struct wireless_dev *wdev,
2108 const void *data,
2109 int data_len)
2110{
2111 int ret = 0;
2112
2113 vos_ssr_protect(__func__);
2114 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2115 vos_ssr_unprotect(__func__);
2116
2117 return ret;
2118
2119
2120}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2122
Dino Mycle6fb96c12014-06-10 11:52:40 +05302123#ifdef WLAN_FEATURE_EXTSCAN
2124static const struct nla_policy
2125wlan_hdd_extscan_config_policy
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2127{
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2129 { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2142 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2144 { .type = NLA_U32 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2146 { .type = NLA_U32 },
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2148 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2156 { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302158 { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2160 { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2162 { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2167 { .type = NLA_UNSPEC },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2169 { .type = NLA_S32 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2171 { .type = NLA_S32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2177 { .type = NLA_U32 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2179 { .type = NLA_BINARY,
2180 .len = IEEE80211_MAX_SSID_LEN + 1 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302182 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2184 { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2188 { .type = NLA_S32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193};
2194
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302195/**
2196 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2197 * @ctx: hdd global context
2198 * @data: capabilities data
2199 *
2200 * Return: none
2201 */
2202static void
2203wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302204{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302205 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302207 tSirEXTScanCapabilitiesEvent *data =
2208 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
2212 if (wlan_hdd_validate_context(pHddCtx))
2213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214 return;
2215 }
2216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302217 if (!pMsg)
2218 {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2220 return;
2221 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 vos_spin_lock_acquire(&hdd_context_lock);
2224
2225 context = &pHddCtx->ext_scan_context;
2226 /* validate response received from target*/
2227 if (context->request_id != data->requestId)
2228 {
2229 vos_spin_lock_release(&hdd_context_lock);
2230 hddLog(LOGE,
2231 FL("Target response id did not match: request_id %d resposne_id %d"),
2232 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302233 return;
2234 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 else
2236 {
2237 context->capability_response = *data;
2238 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239 }
2240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243 return;
2244}
2245
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302246/*
2247 * define short names for the global vendor params
2248 * used by wlan_hdd_send_ext_scan_capability()
2249 */
2250#define PARAM_REQUEST_ID \
2251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2252#define PARAM_STATUS \
2253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2254#define MAX_SCAN_CACHE_SIZE \
2255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2256#define MAX_SCAN_BUCKETS \
2257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2258#define MAX_AP_CACHE_PER_SCAN \
2259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2260#define MAX_RSSI_SAMPLE_SIZE \
2261 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2262#define MAX_SCAN_RPT_THRHOLD \
2263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2264#define MAX_HOTLIST_BSSIDS \
2265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2266#define MAX_BSSID_HISTORY_ENTRIES \
2267 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2268#define MAX_HOTLIST_SSIDS \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302270#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272
2273static int wlan_hdd_send_ext_scan_capability(void *ctx)
2274{
2275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2276 struct sk_buff *skb = NULL;
2277 int ret;
2278 tSirEXTScanCapabilitiesEvent *data;
2279 tANI_U32 nl_buf_len;
2280
2281 ret = wlan_hdd_validate_context(pHddCtx);
2282 if (0 != ret)
2283 {
2284 return ret;
2285 }
2286
2287 data = &(pHddCtx->ext_scan_context.capability_response);
2288
2289 nl_buf_len = NLMSG_HDRLEN;
2290 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2291 (sizeof(data->status) + NLA_HDRLEN) +
2292 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2293 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2294 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2295 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2296 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2297 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2298 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2299 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2300
2301 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2302
2303 if (!skb)
2304 {
2305 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2306 return -ENOMEM;
2307 }
2308
2309 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2310 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2311 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2312 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2313 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2314 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2315 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2316 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2317
2318 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2319 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2320 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2321 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2322 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2323 data->maxApPerScan) ||
2324 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2325 data->maxRssiSampleSize) ||
2326 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2327 data->maxScanReportingThreshold) ||
2328 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2329 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2330 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302331 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2332 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302333 {
2334 hddLog(LOGE, FL("nla put fail"));
2335 goto nla_put_failure;
2336 }
2337
2338 cfg80211_vendor_cmd_reply(skb);
2339 return 0;
2340
2341nla_put_failure:
2342 kfree_skb(skb);
2343 return -EINVAL;;
2344}
2345
2346/*
2347 * done with short names for the global vendor params
2348 * used by wlan_hdd_send_ext_scan_capability()
2349 */
2350#undef PARAM_REQUEST_ID
2351#undef PARAM_STATUS
2352#undef MAX_SCAN_CACHE_SIZE
2353#undef MAX_SCAN_BUCKETS
2354#undef MAX_AP_CACHE_PER_SCAN
2355#undef MAX_RSSI_SAMPLE_SIZE
2356#undef MAX_SCAN_RPT_THRHOLD
2357#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302358#undef MAX_BSSID_HISTORY_ENTRIES
2359#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302360
2361static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2362{
2363 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2364 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302365 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302366 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302369
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302370 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302371 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 if (!pMsg)
2374 {
2375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
2378
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2380 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2381
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302382 context = &pHddCtx->ext_scan_context;
2383 spin_lock(&hdd_context_lock);
2384 if (context->request_id == pData->requestId) {
2385 context->response_status = pData->status ? -EINVAL : 0;
2386 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
2390 /*
2391 * Store the Request ID for comparing with the requestID obtained
2392 * in other requests.HDD shall return a failure is the extscan_stop
2393 * request is issued with a different requestId as that of the
2394 * extscan_start request. Also, This requestId shall be used while
2395 * indicating the full scan results to the upper layers.
2396 * The requestId is stored with the assumption that the firmware
2397 * shall return the ext scan start request's requestId in ext scan
2398 * start response.
2399 */
2400 if (pData->status == 0)
2401 pMac->sme.extScanStartReqId = pData->requestId;
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405}
2406
2407
2408static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2409{
2410 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302412 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 ENTER();
2415
2416 if (wlan_hdd_validate_context(pHddCtx)){
2417 return;
2418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 if (!pMsg)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 return;
2424 }
2425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2427 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302429 context = &pHddCtx->ext_scan_context;
2430 spin_lock(&hdd_context_lock);
2431 if (context->request_id == pData->requestId) {
2432 context->response_status = pData->status ? -EINVAL : 0;
2433 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302435 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439}
2440
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2442 void *pMsg)
2443{
2444 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 tpSirEXTScanSetBssidHotListRspParams pData =
2446 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302447 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302449 ENTER();
2450
2451 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 return;
2453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 if (!pMsg)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2458 return;
2459 }
2460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2462 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302464 context = &pHddCtx->ext_scan_context;
2465 spin_lock(&hdd_context_lock);
2466 if (context->request_id == pData->requestId) {
2467 context->response_status = pData->status ? -EINVAL : 0;
2468 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302470 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302472 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474}
2475
2476static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2477 void *pMsg)
2478{
2479 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480 tpSirEXTScanResetBssidHotlistRspParams pData =
2481 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302482 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302484 ENTER();
2485
2486 if (wlan_hdd_validate_context(pHddCtx)) {
2487 return;
2488 }
2489 if (!pMsg)
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493 }
2494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2496 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302498 context = &pHddCtx->ext_scan_context;
2499 spin_lock(&hdd_context_lock);
2500 if (context->request_id == pData->requestId) {
2501 context->response_status = pData->status ? -EINVAL : 0;
2502 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302504 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302506 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302508}
2509
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302510static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2511 void *pMsg)
2512{
2513 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2514 tpSirEXTScanSetSsidHotListRspParams pData =
2515 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2516 struct hdd_ext_scan_context *context;
2517
2518 if (wlan_hdd_validate_context(pHddCtx)){
2519 return;
2520 }
2521
2522 if (!pMsg)
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2525 return;
2526 }
2527
2528 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2529 pData->status);
2530
2531 context = &pHddCtx->ext_scan_context;
2532 spin_lock(&hdd_context_lock);
2533 if (context->request_id == pData->requestId) {
2534 context->response_status = pData->status ? -EINVAL : 0;
2535 complete(&context->response_event);
2536 }
2537 spin_unlock(&hdd_context_lock);
2538
2539 return;
2540}
2541
2542static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2543 void *pMsg)
2544{
2545 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2546 tpSirEXTScanResetSsidHotlistRspParams pData =
2547 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2548 struct hdd_ext_scan_context *context;
2549
2550 if (wlan_hdd_validate_context(pHddCtx)) {
2551 return;
2552 }
2553 if (!pMsg)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2556 return;
2557 }
2558
2559 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2560 pData->status);
2561
2562 context = &pHddCtx->ext_scan_context;
2563 spin_lock(&hdd_context_lock);
2564 if (context->request_id == pData->requestId) {
2565 context->response_status = pData->status ? -EINVAL : 0;
2566 complete(&context->response_event);
2567 }
2568 spin_unlock(&hdd_context_lock);
2569
2570 return;
2571}
2572
2573
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2575 void *pMsg)
2576{
2577 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2578 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302580 tANI_S32 totalResults;
2581 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2583 struct hdd_ext_scan_context *context;
2584 bool ignore_cached_results = false;
2585 tExtscanCachedScanResult *result;
2586 struct nlattr *nla_results;
2587 tANI_U16 ieLength= 0;
2588 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 ENTER();
2591
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302592 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302593 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302595 if (!pMsg)
2596 {
2597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2598 return;
2599 }
2600
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302601 spin_lock(&hdd_context_lock);
2602 context = &pHddCtx->ext_scan_context;
2603 ignore_cached_results = context->ignore_cached_results;
2604 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302605
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302606 if (ignore_cached_results) {
2607 hddLog(LOGE,
2608 FL("Ignore the cached results received after timeout"));
2609 return;
2610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2613 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302617 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2618 scan_id_index++) {
2619 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 totalResults = result->num_results;
2622 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2623 result->scan_id, result->flags, totalResults);
2624 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 do{
2627 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2628 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2629 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2632 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2633
2634 if (!skb) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed"));
2637 return;
2638 }
2639
2640 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2641
2642 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2643 pData->requestId) ||
2644 nla_put_u32(skb,
2645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2646 resultsPerEvent)) {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2648 goto fail;
2649 }
2650 if (nla_put_u8(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2652 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302653 {
2654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2655 goto fail;
2656 }
2657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302658 if (nla_put_u32(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2660 result->scan_id)) {
2661 hddLog(LOGE, FL("put fail"));
2662 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 nla_results = nla_nest_start(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2667 if (!nla_results)
2668 goto fail;
2669
2670 if (resultsPerEvent) {
2671 struct nlattr *aps;
2672 struct nlattr *nla_result;
2673
2674 nla_result = nla_nest_start(skb, scan_id_index);
2675 if(!nla_result)
2676 goto fail;
2677
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2683 result->flags) ||
2684 nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2686 totalResults)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
2689 }
2690
2691 aps = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2693 if (!aps)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698
2699 head_ptr = (tpSirWifiScanResult) &(result->ap);
2700
2701 for (j = 0; j < resultsPerEvent; j++, i++) {
2702 struct nlattr *ap;
2703 pSirWifiScanResult = head_ptr + i;
2704
2705 /*
2706 * Firmware returns timestamp from WiFi turn ON till
2707 * BSSID was cached (in seconds). Add this with
2708 * time gap between system boot up to WiFi turn ON
2709 * to derive the time since boot when the
2710 * BSSID was cached.
2711 */
2712 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2713 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2714 "Ssid (%s)"
2715 "Bssid: %pM "
2716 "Channel (%u)"
2717 "Rssi (%d)"
2718 "RTT (%u)"
2719 "RTT_SD (%u)"
2720 "Beacon Period %u"
2721 "Capability 0x%x "
2722 "Ie length %d",
2723 i,
2724 pSirWifiScanResult->ts,
2725 pSirWifiScanResult->ssid,
2726 pSirWifiScanResult->bssid,
2727 pSirWifiScanResult->channel,
2728 pSirWifiScanResult->rssi,
2729 pSirWifiScanResult->rtt,
2730 pSirWifiScanResult->rtt_sd,
2731 pSirWifiScanResult->beaconPeriod,
2732 pSirWifiScanResult->capability,
2733 ieLength);
2734
2735 ap = nla_nest_start(skb, j + 1);
2736 if (!ap)
2737 {
2738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2739 goto fail;
2740 }
2741
2742 if (nla_put_u64(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2744 pSirWifiScanResult->ts) )
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2751 sizeof(pSirWifiScanResult->ssid),
2752 pSirWifiScanResult->ssid) )
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757 if (nla_put(skb,
2758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2759 sizeof(pSirWifiScanResult->bssid),
2760 pSirWifiScanResult->bssid) )
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2763 goto fail;
2764 }
2765 if (nla_put_u32(skb,
2766 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2767 pSirWifiScanResult->channel) )
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772 if (nla_put_s32(skb,
2773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2774 pSirWifiScanResult->rssi) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put_u32(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2781 pSirWifiScanResult->rtt) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2788 pSirWifiScanResult->rtt_sd))
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_u32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2795 pSirWifiScanResult->beaconPeriod))
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2802 pSirWifiScanResult->capability))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2809 ieLength))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (ieLength)
2816 if (nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2818 ieLength, ie)) {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822
2823 nla_nest_end(skb, ap);
2824 }
2825 nla_nest_end(skb, aps);
2826 nla_nest_end(skb, nla_result);
2827 }
2828
2829 nla_nest_end(skb, nla_results);
2830
2831 cfg80211_vendor_cmd_reply(skb);
2832
2833 } while (totalResults > 0);
2834 }
2835
2836 if (!pData->moreData) {
2837 spin_lock(&hdd_context_lock);
2838 context->response_status = 0;
2839 complete(&context->response_event);
2840 spin_unlock(&hdd_context_lock);
2841 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 return;
2845fail:
2846 kfree_skb(skb);
2847 return;
2848}
2849
2850static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2851 void *pMsg)
2852{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2855 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302856 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302858 ENTER();
2859
2860 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302861 hddLog(LOGE,
2862 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 return;
2864 }
2865 if (!pMsg)
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302868 return;
2869 }
2870
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 if (pData->bss_found)
2872 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2873 else
2874 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2875
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2878 NULL,
2879#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302882
2883 if (!skb) {
2884 hddLog(VOS_TRACE_LEVEL_ERROR,
2885 FL("cfg80211_vendor_event_alloc failed"));
2886 return;
2887 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2892 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2893
2894 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2896 "Ssid (%s) "
2897 "Bssid (" MAC_ADDRESS_STR ") "
2898 "Channel (%u) "
2899 "Rssi (%d) "
2900 "RTT (%u) "
2901 "RTT_SD (%u) ",
2902 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 pData->bssHotlist[i].ts,
2904 pData->bssHotlist[i].ssid,
2905 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2906 pData->bssHotlist[i].channel,
2907 pData->bssHotlist[i].rssi,
2908 pData->bssHotlist[i].rtt,
2909 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 }
2911
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2918 goto fail;
2919 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 struct nlattr *aps;
2922
2923 aps = nla_nest_start(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2925 if (!aps)
2926 goto fail;
2927
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302928 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 struct nlattr *ap;
2930
2931 ap = nla_nest_start(skb, i + 1);
2932 if (!ap)
2933 goto fail;
2934
2935 if (nla_put_u64(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 nla_put(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 sizeof(pData->bssHotlist[i].ssid),
2941 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302944 sizeof(pData->bssHotlist[i].bssid),
2945 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_s32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 goto fail;
2959
2960 nla_nest_end(skb, ap);
2961 }
2962 nla_nest_end(skb, aps);
2963
2964 if (nla_put_u8(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2966 pData->moreData))
2967 goto fail;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302971 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 return;
2973
2974fail:
2975 kfree_skb(skb);
2976 return;
2977
2978}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302980/**
2981 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2982 * Handle an SSID hotlist match event
2983 * @ctx: HDD context registered with SME
2984 * @event: The SSID hotlist match event
2985 *
2986 * This function will take an SSID match event that was generated by
2987 * firmware and will convert it into a cfg80211 vendor event which is
2988 * sent to userspace.
2989 *
2990 * Return: none
2991 */
2992static void
2993wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2994 void *pMsg)
2995{
2996 hdd_context_t *hdd_ctx = ctx;
2997 struct sk_buff *skb;
2998 tANI_U32 i, index;
2999 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3000
3001 ENTER();
3002
3003 if (wlan_hdd_validate_context(hdd_ctx)) {
3004 hddLog(LOGE,
3005 FL("HDD context is not valid or response"));
3006 return;
3007 }
3008 if (!pMsg)
3009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3011 return;
3012 }
3013
3014 if (pData->ssid_found) {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3016 hddLog(LOG1, "SSID hotlist found");
3017 } else {
3018 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3019 hddLog(LOG1, "SSID hotlist lost");
3020 }
3021
3022 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3024 NULL,
3025#endif
3026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3027 index, GFP_KERNEL);
3028
3029 if (!skb) {
3030 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3031 return;
3032 }
3033 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3034 pData->requestId, pData->numHotlistSsid, pData->moreData);
3035
3036 for (i = 0; i < pData->numHotlistSsid; i++) {
3037 hddLog(LOG1, "[i=%d] Timestamp %llu "
3038 "Ssid: %s "
3039 "Bssid (" MAC_ADDRESS_STR ") "
3040 "Channel %u "
3041 "Rssi %d "
3042 "RTT %u "
3043 "RTT_SD %u",
3044 i,
3045 pData->ssidHotlist[i].ts,
3046 pData->ssidHotlist[i].ssid,
3047 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3048 pData->ssidHotlist[i].channel,
3049 pData->ssidHotlist[i].rssi,
3050 pData->ssidHotlist[i].rtt,
3051 pData->ssidHotlist[i].rtt_sd);
3052 }
3053
3054 if (nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3056 pData->requestId) ||
3057 nla_put_u32(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3059 pData->numHotlistSsid)) {
3060 hddLog(LOGE, FL("put fail"));
3061 goto fail;
3062 }
3063
3064 if (pData->numHotlistSsid) {
3065 struct nlattr *aps;
3066 aps = nla_nest_start(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3068 if (!aps) {
3069 hddLog(LOGE, FL("nest fail"));
3070 goto fail;
3071 }
3072
3073 for (i = 0; i < pData->numHotlistSsid; i++) {
3074 struct nlattr *ap;
3075
3076 ap = nla_nest_start(skb, i);
3077 if (!ap) {
3078 hddLog(LOGE, FL("nest fail"));
3079 goto fail;
3080 }
3081
3082 if (nla_put_u64(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3084 pData->ssidHotlist[i].ts) ||
3085 nla_put(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3087 sizeof(pData->ssidHotlist[i].ssid),
3088 pData->ssidHotlist[i].ssid) ||
3089 nla_put(skb,
3090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3091 sizeof(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].bssid) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3095 pData->ssidHotlist[i].channel) ||
3096 nla_put_s32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3098 pData->ssidHotlist[i].rssi) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3101 pData->ssidHotlist[i].rtt) ||
3102 nla_put_u32(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3104 pData->ssidHotlist[i].rtt_sd)) {
3105 hddLog(LOGE, FL("put fail"));
3106 goto fail;
3107 }
3108 nla_nest_end(skb, ap);
3109 }
3110 nla_nest_end(skb, aps);
3111
3112 if (nla_put_u8(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3114 pData->moreData)) {
3115 hddLog(LOGE, FL("put fail"));
3116 goto fail;
3117 }
3118 }
3119
3120 cfg80211_vendor_event(skb, GFP_KERNEL);
3121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128
3129
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3131 void *pMsg)
3132{
3133 struct sk_buff *skb;
3134 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3135 tpSirWifiFullScanResultEvent pData =
3136 (tpSirWifiFullScanResultEvent) (pMsg);
3137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303138 ENTER();
3139
3140 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303141 hddLog(LOGE,
3142 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 return;
3144 }
3145 if (!pMsg)
3146 {
3147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 return;
3149 }
3150
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303151 /*
3152 * If the full scan result including IE data exceeds NL 4K size
3153 * limitation, drop that beacon/probe rsp frame.
3154 */
3155 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3156 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3157 return;
3158 }
3159
Dino Mycle6fb96c12014-06-10 11:52:40 +05303160 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3162 NULL,
3163#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3166 GFP_KERNEL);
3167
3168 if (!skb) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("cfg80211_vendor_event_alloc failed"));
3171 return;
3172 }
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3177 "Ssid (%s)"
3178 "Bssid (" MAC_ADDRESS_STR ")"
3179 "Channel (%u)"
3180 "Rssi (%d)"
3181 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 "RTT_SD (%u)"
3183 "Bcn Period %d"
3184 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 pData->ap.ts,
3186 pData->ap.ssid,
3187 MAC_ADDR_ARRAY(pData->ap.bssid),
3188 pData->ap.channel,
3189 pData->ap.rssi,
3190 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303191 pData->ap.rtt_sd,
3192 pData->ap.beaconPeriod,
3193 pData->ap.capability);
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3196 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3197 pData->requestId) ||
3198 nla_put_u64(skb,
3199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3200 pData->ap.ts) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3202 sizeof(pData->ap.ssid),
3203 pData->ap.ssid) ||
3204 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3205 WNI_CFG_BSSID_LEN,
3206 pData->ap.bssid) ||
3207 nla_put_u32(skb,
3208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3209 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303210 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 pData->ap.rssi) ||
3212 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3213 pData->ap.rtt) ||
3214 nla_put_u32(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3216 pData->ap.rtt_sd) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3219 pData->ap.beaconPeriod) ||
3220 nla_put_u16(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3222 pData->ap.capability) ||
3223 nla_put_u32(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303225 pData->ieLength) ||
3226 nla_put_u8(skb,
3227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3228 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3231 goto nla_put_failure;
3232 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303233
3234 if (pData->ieLength) {
3235 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3236 pData->ieLength,
3237 pData->ie))
3238 {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3240 goto nla_put_failure;
3241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 }
3243
3244 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246 return;
3247
3248nla_put_failure:
3249 kfree_skb(skb);
3250 return;
3251}
3252
3253static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3254 void *pMsg)
3255{
3256 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3257 struct sk_buff *skb = NULL;
3258 tpSirEXTScanResultsAvailableIndParams pData =
3259 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303261 ENTER();
3262
3263 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264 hddLog(LOGE,
3265 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 return;
3267 }
3268 if (!pMsg)
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 return;
3272 }
3273
3274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3276 NULL,
3277#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3279 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3280 GFP_KERNEL);
3281
3282 if (!skb) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("cfg80211_vendor_event_alloc failed"));
3285 return;
3286 }
3287
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3289 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3290 pData->numResultsAvailable);
3291 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3292 pData->requestId) ||
3293 nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3295 pData->numResultsAvailable)) {
3296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3297 goto nla_put_failure;
3298 }
3299
3300 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303
3304nla_put_failure:
3305 kfree_skb(skb);
3306 return;
3307}
3308
3309static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3310{
3311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3312 struct sk_buff *skb = NULL;
3313 tpSirEXTScanProgressIndParams pData =
3314 (tpSirEXTScanProgressIndParams) pMsg;
3315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303316 ENTER();
3317
3318 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303319 hddLog(LOGE,
3320 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 return;
3322 }
3323 if (!pMsg)
3324 {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
3329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3331 NULL,
3332#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3334 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3335 GFP_KERNEL);
3336
3337 if (!skb) {
3338 hddLog(VOS_TRACE_LEVEL_ERROR,
3339 FL("cfg80211_vendor_event_alloc failed"));
3340 return;
3341 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3344 pData->extScanEventType);
3345 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3346 pData->status);
3347
3348 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3349 pData->extScanEventType) ||
3350 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3352 pData->requestId) ||
3353 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3355 pData->status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3357 goto nla_put_failure;
3358 }
3359
3360 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363
3364nla_put_failure:
3365 kfree_skb(skb);
3366 return;
3367}
3368
3369void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3370 void *pMsg)
3371{
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303374 ENTER();
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 return;
3378 }
3379
3380 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3381
3382
3383 switch(evType) {
3384 case SIR_HAL_EXTSCAN_START_RSP:
3385 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3386 break;
3387
3388 case SIR_HAL_EXTSCAN_STOP_RSP:
3389 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3392 /* There is no need to send this response to upper layer
3393 Just log the message */
3394 hddLog(VOS_TRACE_LEVEL_INFO,
3395 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3396 break;
3397 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3398 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3399 break;
3400
3401 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3402 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3403 break;
3404
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303405 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3406 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3410 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3411 break;
3412
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303414 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 break;
3416 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3417 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3420 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3423 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3424 break;
3425 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3427 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303428 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3429 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3430 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3432 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3433 break;
3434 default:
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3436 break;
3437 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439}
3440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303441static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3442 struct wireless_dev *wdev,
3443 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444{
Dino Myclee8843b32014-07-04 14:21:45 +05303445 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 struct net_device *dev = wdev->netdev;
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3448 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3449 struct nlattr
3450 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3451 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452 struct hdd_ext_scan_context *context;
3453 unsigned long rc;
3454 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 ENTER();
3457
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 return -EINVAL;
3462 }
Dino Myclee8843b32014-07-04 14:21:45 +05303463 /* check the EXTScan Capability */
3464 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3465 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3466 {
3467 hddLog(VOS_TRACE_LEVEL_ERROR,
3468 FL("EXTScan not enabled/supported by Firmware"));
3469 return -EINVAL;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3473 data, dataLen,
3474 wlan_hdd_extscan_config_policy)) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3476 return -EINVAL;
3477 }
3478
3479 /* Parse and fetch request Id */
3480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3482 return -EINVAL;
3483 }
3484
Dino Myclee8843b32014-07-04 14:21:45 +05303485 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Dino Myclee8843b32014-07-04 14:21:45 +05303489 reqMsg.sessionId = pAdapter->sessionId;
3490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303492 vos_spin_lock_acquire(&hdd_context_lock);
3493 context = &pHddCtx->ext_scan_context;
3494 context->request_id = reqMsg.requestId;
3495 INIT_COMPLETION(context->response_event);
3496 vos_spin_lock_release(&hdd_context_lock);
3497
Dino Myclee8843b32014-07-04 14:21:45 +05303498 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303504
3505 rc = wait_for_completion_timeout(&context->response_event,
3506 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3507 if (!rc) {
3508 hddLog(LOGE, FL("Target response timed out"));
3509 return -ETIMEDOUT;
3510 }
3511
3512 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3513 if (ret)
3514 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3515
3516 return ret;
3517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303518 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return 0;
3520}
3521
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303522static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3523 struct wireless_dev *wdev,
3524 const void *data, int dataLen)
3525{
3526 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303528 vos_ssr_protect(__func__);
3529 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3530 vos_ssr_unprotect(__func__);
3531
3532 return ret;
3533}
3534
3535static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3536 struct wireless_dev *wdev,
3537 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538{
Dino Myclee8843b32014-07-04 14:21:45 +05303539 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 struct net_device *dev = wdev->netdev;
3541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3543 struct nlattr
3544 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3545 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 struct hdd_ext_scan_context *context;
3547 unsigned long rc;
3548 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 ENTER();
3551
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303552 if (VOS_FTM_MODE == hdd_get_conparam()) {
3553 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3554 return -EINVAL;
3555 }
3556
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 status = wlan_hdd_validate_context(pHddCtx);
3558 if (0 != status)
3559 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 return -EINVAL;
3561 }
Dino Myclee8843b32014-07-04 14:21:45 +05303562 /* check the EXTScan Capability */
3563 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3564 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 FL("EXTScan not enabled/supported by Firmware"));
3568 return -EINVAL;
3569 }
3570
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3572 data, dataLen,
3573 wlan_hdd_extscan_config_policy)) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3575 return -EINVAL;
3576 }
3577 /* Parse and fetch request Id */
3578 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3580 return -EINVAL;
3581 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582
Dino Myclee8843b32014-07-04 14:21:45 +05303583 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585
Dino Myclee8843b32014-07-04 14:21:45 +05303586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587
Dino Myclee8843b32014-07-04 14:21:45 +05303588 reqMsg.sessionId = pAdapter->sessionId;
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
3591 /* Parse and fetch flush parameter */
3592 if (!tb
3593 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3596 goto failed;
3597 }
Dino Myclee8843b32014-07-04 14:21:45 +05303598 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3600
Dino Myclee8843b32014-07-04 14:21:45 +05303601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303603 spin_lock(&hdd_context_lock);
3604 context = &pHddCtx->ext_scan_context;
3605 context->request_id = reqMsg.requestId;
3606 context->ignore_cached_results = false;
3607 INIT_COMPLETION(context->response_event);
3608 spin_unlock(&hdd_context_lock);
3609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 if (!HAL_STATUS_SUCCESS(status)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303614 return -EINVAL;
3615 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616
3617 rc = wait_for_completion_timeout(&context->response_event,
3618 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3619 if (!rc) {
3620 hddLog(LOGE, FL("Target response timed out"));
3621 retval = -ETIMEDOUT;
3622 spin_lock(&hdd_context_lock);
3623 context->ignore_cached_results = true;
3624 spin_unlock(&hdd_context_lock);
3625 } else {
3626 spin_lock(&hdd_context_lock);
3627 retval = context->response_status;
3628 spin_unlock(&hdd_context_lock);
3629 }
3630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303631 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
3634failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635 return -EINVAL;
3636}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303637static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3638 struct wireless_dev *wdev,
3639 const void *data, int dataLen)
3640{
3641 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303643 vos_ssr_protect(__func__);
3644 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3645 vos_ssr_unprotect(__func__);
3646
3647 return ret;
3648}
3649
3650static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303652 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653{
3654 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3655 struct net_device *dev = wdev->netdev;
3656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3658 struct nlattr
3659 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3660 struct nlattr
3661 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3662 struct nlattr *apTh;
3663 eHalStatus status;
3664 tANI_U8 i = 0;
3665 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303666 struct hdd_ext_scan_context *context;
3667 tANI_U32 request_id;
3668 unsigned long rc;
3669 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 ENTER();
3672
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303673 if (VOS_FTM_MODE == hdd_get_conparam()) {
3674 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3675 return -EINVAL;
3676 }
3677
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 status = wlan_hdd_validate_context(pHddCtx);
3679 if (0 != status)
3680 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3705 vos_mem_malloc(sizeof(*pReqMsg));
3706 if (!pReqMsg) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3708 return -ENOMEM;
3709 }
3710
Dino Myclee8843b32014-07-04 14:21:45 +05303711
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 pReqMsg->requestId = nla_get_u32(
3713 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3715
3716 /* Parse and fetch number of APs */
3717 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3719 goto fail;
3720 }
3721
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303722 /* Parse and fetch lost ap sample size */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3724 hddLog(LOGE, FL("attr lost ap sample size failed"));
3725 goto fail;
3726 }
3727
3728 pReqMsg->lostBssidSampleSize = nla_get_u32(
3729 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3730 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3731
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732 pReqMsg->sessionId = pAdapter->sessionId;
3733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3734
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303735 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 nla_for_each_nested(apTh,
3740 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3741 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 nla_data(apTh), nla_len(apTh),
3743 NULL)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3745 goto fail;
3746 }
3747
3748 /* Parse and fetch MAC address */
3749 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3751 goto fail;
3752 }
3753 memcpy(pReqMsg->ap[i].bssid, nla_data(
3754 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3755 sizeof(tSirMacAddr));
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3757
3758 /* Parse and fetch low RSSI */
3759 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3761 goto fail;
3762 }
3763 pReqMsg->ap[i].low = nla_get_s32(
3764 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3766
3767 /* Parse and fetch high RSSI */
3768 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3770 goto fail;
3771 }
3772 pReqMsg->ap[i].high = nla_get_s32(
3773 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3774 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3775 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776 i++;
3777 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303778
3779 context = &pHddCtx->ext_scan_context;
3780 spin_lock(&hdd_context_lock);
3781 INIT_COMPLETION(context->response_event);
3782 context->request_id = request_id = pReqMsg->requestId;
3783 spin_unlock(&hdd_context_lock);
3784
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3786 if (!HAL_STATUS_SUCCESS(status)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("sme_SetBssHotlist failed(err=%d)"), status);
3789 vos_mem_free(pReqMsg);
3790 return -EINVAL;
3791 }
3792
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303793 /* request was sent -- wait for the response */
3794 rc = wait_for_completion_timeout(&context->response_event,
3795 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3796
3797 if (!rc) {
3798 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3799 retval = -ETIMEDOUT;
3800 } else {
3801 spin_lock(&hdd_context_lock);
3802 if (context->request_id == request_id)
3803 retval = context->response_status;
3804 else
3805 retval = -EINVAL;
3806 spin_unlock(&hdd_context_lock);
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303810 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303811 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
3813fail:
3814 vos_mem_free(pReqMsg);
3815 return -EINVAL;
3816}
3817
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303818static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3819 struct wireless_dev *wdev,
3820 const void *data, int dataLen)
3821{
3822 int ret = 0;
3823
3824 vos_ssr_protect(__func__);
3825 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3826 dataLen);
3827 vos_ssr_unprotect(__func__);
3828
3829 return ret;
3830}
3831
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303832/*
3833 * define short names for the global vendor params
3834 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3835 */
3836#define PARAM_MAX \
3837QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3838#define PARAM_REQUEST_ID \
3839QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3840#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3841QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3842#define PARAMS_NUM_SSID \
3843QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3844#define THRESHOLD_PARAM \
3845QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3846#define PARAM_SSID \
3847QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3848#define PARAM_BAND \
3849QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3850#define PARAM_RSSI_LOW \
3851QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3852#define PARAM_RSSI_HIGH \
3853QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3854
3855/**
3856 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3857 * @wiphy: Pointer to wireless phy
3858 * @wdev: Pointer to wireless device
3859 * @data: Pointer to data
3860 * @data_len: Data length
3861 *
3862 * Return: 0 on success, negative errno on failure
3863 */
3864static int
3865__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data,
3868 int data_len)
3869{
3870 tSirEXTScanSetSsidHotListReqParams *request;
3871 struct net_device *dev = wdev->netdev;
3872 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3873 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3874 struct nlattr *tb[PARAM_MAX + 1];
3875 struct nlattr *tb2[PARAM_MAX + 1];
3876 struct nlattr *ssids;
3877 struct hdd_ext_scan_context *context;
3878 uint32_t request_id;
3879 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3880 int ssid_len;
3881 eHalStatus status;
3882 int i, rem, retval;
3883 unsigned long rc;
3884
3885 ENTER();
3886
3887 if (VOS_FTM_MODE == hdd_get_conparam()) {
3888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3889 return -EINVAL;
3890 }
3891
3892 retval = wlan_hdd_validate_context(hdd_ctx);
3893 if (0 != retval) {
3894 hddLog(LOGE, FL("HDD context is not valid"));
3895 return -EINVAL;
3896 }
3897
3898 /* check the EXTScan Capability */
3899 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3901 {
3902 hddLog(VOS_TRACE_LEVEL_ERROR,
3903 FL("EXTScan not enabled/supported by Firmware"));
3904 return -EINVAL;
3905 }
3906
3907 if (nla_parse(tb, PARAM_MAX,
3908 data, data_len,
3909 wlan_hdd_extscan_config_policy)) {
3910 hddLog(LOGE, FL("Invalid ATTR"));
3911 return -EINVAL;
3912 }
3913
3914 request = vos_mem_malloc(sizeof(*request));
3915 if (!request) {
3916 hddLog(LOGE, FL("vos_mem_malloc failed"));
3917 return -ENOMEM;
3918 }
3919
3920 /* Parse and fetch request Id */
3921 if (!tb[PARAM_REQUEST_ID]) {
3922 hddLog(LOGE, FL("attr request id failed"));
3923 goto fail;
3924 }
3925
3926 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3927 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3928
3929 /* Parse and fetch lost SSID sample size */
3930 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3931 hddLog(LOGE, FL("attr number of Ssid failed"));
3932 goto fail;
3933 }
3934 request->lost_ssid_sample_size =
3935 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3936 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3937 request->lost_ssid_sample_size);
3938
3939 /* Parse and fetch number of hotlist SSID */
3940 if (!tb[PARAMS_NUM_SSID]) {
3941 hddLog(LOGE, FL("attr number of Ssid failed"));
3942 goto fail;
3943 }
3944 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3945 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3946
3947 request->session_id = adapter->sessionId;
3948 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3949
3950 i = 0;
3951 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3952 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3953 hddLog(LOGE,
3954 FL("Too Many SSIDs, %d exceeds %d"),
3955 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3956 break;
3957 }
3958 if (nla_parse(tb2, PARAM_MAX,
3959 nla_data(ssids), nla_len(ssids),
3960 wlan_hdd_extscan_config_policy)) {
3961 hddLog(LOGE, FL("nla_parse failed"));
3962 goto fail;
3963 }
3964
3965 /* Parse and fetch SSID */
3966 if (!tb2[PARAM_SSID]) {
3967 hddLog(LOGE, FL("attr ssid failed"));
3968 goto fail;
3969 }
3970 nla_memcpy(ssid_string,
3971 tb2[PARAM_SSID],
3972 sizeof(ssid_string));
3973 hddLog(LOG1, FL("SSID %s"),
3974 ssid_string);
3975 ssid_len = strlen(ssid_string);
3976 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3977 request->ssid[i].ssid.length = ssid_len;
3978 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3979 hddLog(LOG1, FL("After copying SSID %s"),
3980 request->ssid[i].ssid.ssId);
3981 hddLog(LOG1, FL("After copying length: %d"),
3982 ssid_len);
3983
3984 /* Parse and fetch low RSSI */
3985 if (!tb2[PARAM_BAND]) {
3986 hddLog(LOGE, FL("attr band failed"));
3987 goto fail;
3988 }
3989 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3990 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3991
3992 /* Parse and fetch low RSSI */
3993 if (!tb2[PARAM_RSSI_LOW]) {
3994 hddLog(LOGE, FL("attr low RSSI failed"));
3995 goto fail;
3996 }
3997 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3998 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3999
4000 /* Parse and fetch high RSSI */
4001 if (!tb2[PARAM_RSSI_HIGH]) {
4002 hddLog(LOGE, FL("attr high RSSI failed"));
4003 goto fail;
4004 }
4005 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4006 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4007 i++;
4008 }
4009
4010 context = &hdd_ctx->ext_scan_context;
4011 spin_lock(&hdd_context_lock);
4012 INIT_COMPLETION(context->response_event);
4013 context->request_id = request_id = request->request_id;
4014 spin_unlock(&hdd_context_lock);
4015
4016 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4017 if (!HAL_STATUS_SUCCESS(status)) {
4018 hddLog(LOGE,
4019 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4020 goto fail;
4021 }
4022
4023 vos_mem_free(request);
4024
4025 /* request was sent -- wait for the response */
4026 rc = wait_for_completion_timeout(&context->response_event,
4027 msecs_to_jiffies
4028 (WLAN_WAIT_TIME_EXTSCAN));
4029 if (!rc) {
4030 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4031 retval = -ETIMEDOUT;
4032 } else {
4033 spin_lock(&hdd_context_lock);
4034 if (context->request_id == request_id)
4035 retval = context->response_status;
4036 else
4037 retval = -EINVAL;
4038 spin_unlock(&hdd_context_lock);
4039 }
4040
4041 return retval;
4042
4043fail:
4044 vos_mem_free(request);
4045 return -EINVAL;
4046}
4047
4048/*
4049 * done with short names for the global vendor params
4050 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4051 */
4052#undef PARAM_MAX
4053#undef PARAM_REQUEST_ID
4054#undef PARAMS_NUM_SSID
4055#undef THRESHOLD_PARAM
4056#undef PARAM_SSID
4057#undef PARAM_BAND
4058#undef PARAM_RSSI_LOW
4059#undef PARAM_RSSI_HIGH
4060
4061static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4062 struct wireless_dev *wdev,
4063 const void *data, int dataLen)
4064{
4065 int ret = 0;
4066
4067 vos_ssr_protect(__func__);
4068 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4069 dataLen);
4070 vos_ssr_unprotect(__func__);
4071
4072 return ret;
4073}
4074
4075static int
4076__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4077 struct wireless_dev *wdev,
4078 const void *data,
4079 int data_len)
4080{
4081 tSirEXTScanResetSsidHotlistReqParams request;
4082 struct net_device *dev = wdev->netdev;
4083 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4084 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4085 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4086 struct hdd_ext_scan_context *context;
4087 uint32_t request_id;
4088 eHalStatus status;
4089 int retval;
4090 unsigned long rc;
4091
4092 ENTER();
4093
4094 if (VOS_FTM_MODE == hdd_get_conparam()) {
4095 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4096 return -EINVAL;
4097 }
4098
4099 retval = wlan_hdd_validate_context(hdd_ctx);
4100 if (0 != retval) {
4101 hddLog(LOGE, FL("HDD context is not valid"));
4102 return -EINVAL;
4103 }
4104
4105 /* check the EXTScan Capability */
4106 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4107 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4108 {
4109 hddLog(LOGE,
4110 FL("EXTScan not enabled/supported by Firmware"));
4111 return -EINVAL;
4112 }
4113
4114 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4115 data, data_len,
4116 wlan_hdd_extscan_config_policy)) {
4117 hddLog(LOGE, FL("Invalid ATTR"));
4118 return -EINVAL;
4119 }
4120
4121 /* Parse and fetch request Id */
4122 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4123 hddLog(LOGE, FL("attr request id failed"));
4124 return -EINVAL;
4125 }
4126
4127 request.requestId = nla_get_u32(
4128 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4129 request.sessionId = adapter->sessionId;
4130 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4131 request.sessionId);
4132
4133 context = &hdd_ctx->ext_scan_context;
4134 spin_lock(&hdd_context_lock);
4135 INIT_COMPLETION(context->response_event);
4136 context->request_id = request_id = request.requestId;
4137 spin_unlock(&hdd_context_lock);
4138
4139 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4140 if (!HAL_STATUS_SUCCESS(status)) {
4141 hddLog(LOGE,
4142 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4143 return -EINVAL;
4144 }
4145
4146 /* request was sent -- wait for the response */
4147 rc = wait_for_completion_timeout(&context->response_event,
4148 msecs_to_jiffies
4149 (WLAN_WAIT_TIME_EXTSCAN));
4150 if (!rc) {
4151 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4152 retval = -ETIMEDOUT;
4153 } else {
4154 spin_lock(&hdd_context_lock);
4155 if (context->request_id == request_id)
4156 retval = context->response_status;
4157 else
4158 retval = -EINVAL;
4159 spin_unlock(&hdd_context_lock);
4160 }
4161
4162 return retval;
4163}
4164
4165static int
4166wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4167 struct wireless_dev *wdev,
4168 const void *data,
4169 int data_len)
4170{
4171 int ret;
4172
4173 vos_ssr_protect(__func__);
4174 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4175 data, data_len);
4176 vos_ssr_unprotect(__func__);
4177
4178 return ret;
4179}
4180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304181static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304183 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184{
4185 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4186 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4187 tANI_U8 numChannels = 0;
4188 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304189 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 tWifiBand wifiBand;
4191 eHalStatus status;
4192 struct sk_buff *replySkb;
4193 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304194 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 status = wlan_hdd_validate_context(pHddCtx);
4199 if (0 != status)
4200 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 return -EINVAL;
4202 }
Dino Myclee8843b32014-07-04 14:21:45 +05304203
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4205 data, dataLen,
4206 wlan_hdd_extscan_config_policy)) {
4207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4208 return -EINVAL;
4209 }
4210
4211 /* Parse and fetch request Id */
4212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4214 return -EINVAL;
4215 }
4216 requestId = nla_get_u32(
4217 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4219
4220 /* Parse and fetch wifi band */
4221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4222 {
4223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4224 return -EINVAL;
4225 }
4226 wifiBand = nla_get_u32(
4227 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4229
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304230 /* Parse and fetch max channels */
4231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4232 {
4233 hddLog(LOGE, FL("attr max channels failed"));
4234 return -EINVAL;
4235 }
4236 maxChannels = nla_get_u32(
4237 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4241 wifiBand, ChannelList,
4242 &numChannels);
4243 if (eHAL_STATUS_SUCCESS != status) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR,
4245 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4246 return -EINVAL;
4247 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304248
4249 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304251
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252 for (i = 0; i < numChannels; i++)
4253 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4254
4255 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4256 sizeof(u32) * numChannels +
4257 NLMSG_HDRLEN);
4258
4259 if (!replySkb) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("valid channels: buffer alloc fail"));
4262 return -EINVAL;
4263 }
4264 if (nla_put_u32(replySkb,
4265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4266 numChannels) ||
4267 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4268 sizeof(u32) * numChannels, ChannelList)) {
4269
4270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4271 kfree_skb(replySkb);
4272 return -EINVAL;
4273 }
4274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304275 ret = cfg80211_vendor_cmd_reply(replySkb);
4276
4277 EXIT();
4278 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279}
4280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304281static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4282 struct wireless_dev *wdev,
4283 const void *data, int dataLen)
4284{
4285 int ret = 0;
4286
4287 vos_ssr_protect(__func__);
4288 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4289 dataLen);
4290 vos_ssr_unprotect(__func__);
4291
4292 return ret;
4293}
4294
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304295static int hdd_extscan_start_fill_bucket_channel_spec(
4296 hdd_context_t *pHddCtx,
4297 tpSirEXTScanStartReqParams pReqMsg,
4298 struct nlattr **tb)
4299{
4300 struct nlattr *bucket[
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4302 struct nlattr *channel[
4303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4304 struct nlattr *buckets;
4305 struct nlattr *channels;
4306 int rem1, rem2;
4307 eHalStatus status;
4308 tANI_U8 bktIndex, j, numChannels;
4309 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4310 tANI_U32 passive_max_chn_time, active_max_chn_time;
4311
4312 bktIndex = 0;
4313
4314 nla_for_each_nested(buckets,
4315 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4316 if (nla_parse(bucket,
4317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4318 nla_data(buckets), nla_len(buckets), NULL)) {
4319 hddLog(LOGE, FL("nla_parse failed"));
4320 return -EINVAL;
4321 }
4322
4323 /* Parse and fetch bucket spec */
4324 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4325 hddLog(LOGE, FL("attr bucket index failed"));
4326 return -EINVAL;
4327 }
4328 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4329 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4330 hddLog(LOG1, FL("Bucket spec Index %d"),
4331 pReqMsg->buckets[bktIndex].bucket);
4332
4333 /* Parse and fetch wifi band */
4334 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4335 hddLog(LOGE, FL("attr wifi band failed"));
4336 return -EINVAL;
4337 }
4338 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4339 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4340 hddLog(LOG1, FL("Wifi band %d"),
4341 pReqMsg->buckets[bktIndex].band);
4342
4343 /* Parse and fetch period */
4344 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4345 hddLog(LOGE, FL("attr period failed"));
4346 return -EINVAL;
4347 }
4348 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4349 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4350 hddLog(LOG1, FL("period %d"),
4351 pReqMsg->buckets[bktIndex].period);
4352
4353 /* Parse and fetch report events */
4354 if (!bucket[
4355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4356 hddLog(LOGE, FL("attr report events failed"));
4357 return -EINVAL;
4358 }
4359 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4360 bucket[
4361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4362 hddLog(LOG1, FL("report events %d"),
4363 pReqMsg->buckets[bktIndex].reportEvents);
4364
4365 /* Parse and fetch max period */
4366 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4367 hddLog(LOGE, FL("attr max period failed"));
4368 return -EINVAL;
4369 }
4370 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4371 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4372 hddLog(LOG1, FL("max period %u"),
4373 pReqMsg->buckets[bktIndex].max_period);
4374
4375 /* Parse and fetch exponent */
4376 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4377 hddLog(LOGE, FL("attr exponent failed"));
4378 return -EINVAL;
4379 }
4380 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4381 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4382 hddLog(LOG1, FL("exponent %u"),
4383 pReqMsg->buckets[bktIndex].exponent);
4384
4385 /* Parse and fetch step count */
4386 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4387 hddLog(LOGE, FL("attr step count failed"));
4388 return -EINVAL;
4389 }
4390 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4391 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4392 hddLog(LOG1, FL("Step count %u"),
4393 pReqMsg->buckets[bktIndex].step_count);
4394
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4396 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4397
4398 /* Framework shall pass the channel list if the input WiFi band is
4399 * WIFI_BAND_UNSPECIFIED.
4400 * If the input WiFi band is specified (any value other than
4401 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4402 */
4403 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4404 numChannels = 0;
4405 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4406 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4407 pReqMsg->buckets[bktIndex].band,
4408 chanList, &numChannels);
4409 if (!HAL_STATUS_SUCCESS(status)) {
4410 hddLog(LOGE,
4411 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4412 status);
4413 return -EINVAL;
4414 }
4415
4416 pReqMsg->buckets[bktIndex].numChannels =
4417 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4418 hddLog(LOG1, FL("Num channels %d"),
4419 pReqMsg->buckets[bktIndex].numChannels);
4420
4421 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4422 j++) {
4423 pReqMsg->buckets[bktIndex].channels[j].channel =
4424 chanList[j];
4425 pReqMsg->buckets[bktIndex].channels[j].
4426 chnlClass = 0;
4427 if (CSR_IS_CHANNEL_DFS(
4428 vos_freq_to_chan(chanList[j]))) {
4429 pReqMsg->buckets[bktIndex].channels[j].
4430 passive = 1;
4431 pReqMsg->buckets[bktIndex].channels[j].
4432 dwellTimeMs = passive_max_chn_time;
4433 } else {
4434 pReqMsg->buckets[bktIndex].channels[j].
4435 passive = 0;
4436 pReqMsg->buckets[bktIndex].channels[j].
4437 dwellTimeMs = active_max_chn_time;
4438 }
4439
4440 hddLog(LOG1,
4441 "Channel %u Passive %u Dwell time %u ms",
4442 pReqMsg->buckets[bktIndex].channels[j].channel,
4443 pReqMsg->buckets[bktIndex].channels[j].passive,
4444 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4445 }
4446
4447 bktIndex++;
4448 continue;
4449 }
4450
4451 /* Parse and fetch number of channels */
4452 if (!bucket[
4453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4454 hddLog(LOGE, FL("attr num channels failed"));
4455 return -EINVAL;
4456 }
4457
4458 pReqMsg->buckets[bktIndex].numChannels =
4459 nla_get_u32(bucket[
4460 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4461 hddLog(LOG1, FL("num channels %d"),
4462 pReqMsg->buckets[bktIndex].numChannels);
4463
4464 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4465 hddLog(LOGE, FL("attr channel spec failed"));
4466 return -EINVAL;
4467 }
4468
4469 j = 0;
4470 nla_for_each_nested(channels,
4471 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4472 if (nla_parse(channel,
4473 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4474 nla_data(channels), nla_len(channels),
4475 wlan_hdd_extscan_config_policy)) {
4476 hddLog(LOGE, FL("nla_parse failed"));
4477 return -EINVAL;
4478 }
4479
4480 /* Parse and fetch channel */
4481 if (!channel[
4482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4483 hddLog(LOGE, FL("attr channel failed"));
4484 return -EINVAL;
4485 }
4486 pReqMsg->buckets[bktIndex].channels[j].channel =
4487 nla_get_u32(channel[
4488 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4489 hddLog(LOG1, FL("channel %u"),
4490 pReqMsg->buckets[bktIndex].channels[j].channel);
4491
4492 /* Parse and fetch dwell time */
4493 if (!channel[
4494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4495 hddLog(LOGE, FL("attr dwelltime failed"));
4496 return -EINVAL;
4497 }
4498 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4499 nla_get_u32(channel[
4500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4501
4502 hddLog(LOG1, FL("Dwell time (%u ms)"),
4503 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4504
4505
4506 /* Parse and fetch channel spec passive */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4509 hddLog(LOGE,
4510 FL("attr channel spec passive failed"));
4511 return -EINVAL;
4512 }
4513 pReqMsg->buckets[bktIndex].channels[j].passive =
4514 nla_get_u8(channel[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4516 hddLog(LOG1, FL("Chnl spec passive %u"),
4517 pReqMsg->buckets[bktIndex].channels[j].passive);
4518
4519 j++;
4520 }
4521
4522 bktIndex++;
4523 }
4524
4525 return 0;
4526}
4527
4528
4529/*
4530 * define short names for the global vendor params
4531 * used by wlan_hdd_cfg80211_extscan_start()
4532 */
4533#define PARAM_MAX \
4534QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4535#define PARAM_REQUEST_ID \
4536QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4537#define PARAM_BASE_PERIOD \
4538QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4539#define PARAM_MAX_AP_PER_SCAN \
4540QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4541#define PARAM_RPT_THRHLD_PERCENT \
4542QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4543#define PARAM_RPT_THRHLD_NUM_SCANS \
4544QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4545#define PARAM_NUM_BUCKETS \
4546QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4547
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304548static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304550 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551{
Dino Myclee8843b32014-07-04 14:21:45 +05304552 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304553 struct net_device *dev = wdev->netdev;
4554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4555 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4556 struct nlattr *tb[PARAM_MAX + 1];
4557 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304559 tANI_U32 request_id;
4560 struct hdd_ext_scan_context *context;
4561 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304563 ENTER();
4564
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304565 if (VOS_FTM_MODE == hdd_get_conparam()) {
4566 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4567 return -EINVAL;
4568 }
4569
Dino Mycle6fb96c12014-06-10 11:52:40 +05304570 status = wlan_hdd_validate_context(pHddCtx);
4571 if (0 != status)
4572 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304573 return -EINVAL;
4574 }
Dino Myclee8843b32014-07-04 14:21:45 +05304575 /* check the EXTScan Capability */
4576 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4577 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4578 {
4579 hddLog(VOS_TRACE_LEVEL_ERROR,
4580 FL("EXTScan not enabled/supported by Firmware"));
4581 return -EINVAL;
4582 }
4583
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 data, dataLen,
4586 wlan_hdd_extscan_config_policy)) {
4587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4588 return -EINVAL;
4589 }
4590
4591 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304592 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4594 return -EINVAL;
4595 }
4596
Dino Myclee8843b32014-07-04 14:21:45 +05304597 pReqMsg = (tpSirEXTScanStartReqParams)
4598 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4601 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 }
4603
4604 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304605 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4607
4608 pReqMsg->sessionId = pAdapter->sessionId;
4609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4610
4611 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304612 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4614 goto fail;
4615 }
4616 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304617 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4619 pReqMsg->basePeriod);
4620
4621 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304622 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4624 goto fail;
4625 }
4626 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304627 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4629 pReqMsg->maxAPperScan);
4630
4631 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4634 goto fail;
4635 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 pReqMsg->reportThresholdPercent = nla_get_u8(
4637 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 pReqMsg->reportThresholdPercent);
4640
4641 /* Parse and fetch report threshold num scans */
4642 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4643 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4644 goto fail;
4645 }
4646 pReqMsg->reportThresholdNumScans = nla_get_u8(
4647 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4648 hddLog(LOG1, FL("Report Threshold num scans %d"),
4649 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650
4651 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304652 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4654 goto fail;
4655 }
4656 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4659 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4660 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4661 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4662 }
4663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4664 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4668 goto fail;
4669 }
4670
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4674 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304675
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304676 context = &pHddCtx->ext_scan_context;
4677 spin_lock(&hdd_context_lock);
4678 INIT_COMPLETION(context->response_event);
4679 context->request_id = request_id = pReqMsg->requestId;
4680 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304681
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4683 if (!HAL_STATUS_SUCCESS(status)) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 goto fail;
4687 }
4688
4689 /* request was sent -- wait for the response */
4690 rc = wait_for_completion_timeout(&context->response_event,
4691 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4692
4693 if (!rc) {
4694 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4695 retval = -ETIMEDOUT;
4696 } else {
4697 spin_lock(&hdd_context_lock);
4698 if (context->request_id == request_id)
4699 retval = context->response_status;
4700 else
4701 retval = -EINVAL;
4702 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 }
4704
Dino Myclee8843b32014-07-04 14:21:45 +05304705 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304706 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
4709fail:
4710 vos_mem_free(pReqMsg);
4711 return -EINVAL;
4712}
4713
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714/*
4715 * done with short names for the global vendor params
4716 * used by wlan_hdd_cfg80211_extscan_start()
4717 */
4718#undef PARAM_MAX
4719#undef PARAM_REQUEST_ID
4720#undef PARAM_BASE_PERIOD
4721#undef PARAMS_MAX_AP_PER_SCAN
4722#undef PARAMS_RPT_THRHLD_PERCENT
4723#undef PARAMS_RPT_THRHLD_NUM_SCANS
4724#undef PARAMS_NUM_BUCKETS
4725
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304726static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4727 struct wireless_dev *wdev,
4728 const void *data, int dataLen)
4729{
4730 int ret = 0;
4731
4732 vos_ssr_protect(__func__);
4733 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4734 vos_ssr_unprotect(__func__);
4735
4736 return ret;
4737}
4738
4739static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304741 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742{
Dino Myclee8843b32014-07-04 14:21:45 +05304743 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 struct net_device *dev = wdev->netdev;
4745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4748 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304749 int retval;
4750 unsigned long rc;
4751 struct hdd_ext_scan_context *context;
4752 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304754 ENTER();
4755
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304756 if (VOS_FTM_MODE == hdd_get_conparam()) {
4757 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4758 return -EINVAL;
4759 }
4760
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 status = wlan_hdd_validate_context(pHddCtx);
4762 if (0 != status)
4763 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 return -EINVAL;
4765 }
Dino Myclee8843b32014-07-04 14:21:45 +05304766 /* check the EXTScan Capability */
4767 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4768 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR,
4771 FL("EXTScan not enabled/supported by Firmware"));
4772 return -EINVAL;
4773 }
4774
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4776 data, dataLen,
4777 wlan_hdd_extscan_config_policy)) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4779 return -EINVAL;
4780 }
4781
4782 /* Parse and fetch request Id */
4783 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4785 return -EINVAL;
4786 }
4787
Dino Myclee8843b32014-07-04 14:21:45 +05304788 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Dino Myclee8843b32014-07-04 14:21:45 +05304792 reqMsg.sessionId = pAdapter->sessionId;
4793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304795 context = &pHddCtx->ext_scan_context;
4796 spin_lock(&hdd_context_lock);
4797 INIT_COMPLETION(context->response_event);
4798 context->request_id = request_id = reqMsg.sessionId;
4799 spin_unlock(&hdd_context_lock);
4800
Dino Myclee8843b32014-07-04 14:21:45 +05304801 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (!HAL_STATUS_SUCCESS(status)) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR,
4804 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 return -EINVAL;
4806 }
4807
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304808 /* request was sent -- wait for the response */
4809 rc = wait_for_completion_timeout(&context->response_event,
4810 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4811
4812 if (!rc) {
4813 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4814 retval = -ETIMEDOUT;
4815 } else {
4816 spin_lock(&hdd_context_lock);
4817 if (context->request_id == request_id)
4818 retval = context->response_status;
4819 else
4820 retval = -EINVAL;
4821 spin_unlock(&hdd_context_lock);
4822 }
4823
4824 return retval;
4825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304826 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 return 0;
4828}
4829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304830static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4831 struct wireless_dev *wdev,
4832 const void *data, int dataLen)
4833{
4834 int ret = 0;
4835
4836 vos_ssr_protect(__func__);
4837 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4838 vos_ssr_unprotect(__func__);
4839
4840 return ret;
4841}
4842
4843static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304845 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846{
Dino Myclee8843b32014-07-04 14:21:45 +05304847 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 struct net_device *dev = wdev->netdev;
4849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4851 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4852 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304853 struct hdd_ext_scan_context *context;
4854 tANI_U32 request_id;
4855 unsigned long rc;
4856 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304858 ENTER();
4859
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304860 if (VOS_FTM_MODE == hdd_get_conparam()) {
4861 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4862 return -EINVAL;
4863 }
4864
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865 status = wlan_hdd_validate_context(pHddCtx);
4866 if (0 != status)
4867 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304868 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304869 return -EINVAL;
4870 }
Dino Myclee8843b32014-07-04 14:21:45 +05304871 /* check the EXTScan Capability */
4872 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4873 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4874 {
4875 hddLog(VOS_TRACE_LEVEL_ERROR,
4876 FL("EXTScan not enabled/supported by Firmware"));
4877 return -EINVAL;
4878 }
4879
Dino Mycle6fb96c12014-06-10 11:52:40 +05304880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4881 data, dataLen,
4882 wlan_hdd_extscan_config_policy)) {
4883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4884 return -EINVAL;
4885 }
4886
4887 /* Parse and fetch request Id */
4888 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4890 return -EINVAL;
4891 }
4892
Dino Myclee8843b32014-07-04 14:21:45 +05304893 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Dino Myclee8843b32014-07-04 14:21:45 +05304897 reqMsg.sessionId = pAdapter->sessionId;
4898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304900 context = &pHddCtx->ext_scan_context;
4901 spin_lock(&hdd_context_lock);
4902 INIT_COMPLETION(context->response_event);
4903 context->request_id = request_id = reqMsg.requestId;
4904 spin_unlock(&hdd_context_lock);
4905
Dino Myclee8843b32014-07-04 14:21:45 +05304906 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 if (!HAL_STATUS_SUCCESS(status)) {
4908 hddLog(VOS_TRACE_LEVEL_ERROR,
4909 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304910 return -EINVAL;
4911 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912
4913 /* request was sent -- wait for the response */
4914 rc = wait_for_completion_timeout(&context->response_event,
4915 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4916 if (!rc) {
4917 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4918 retval = -ETIMEDOUT;
4919 } else {
4920 spin_lock(&hdd_context_lock);
4921 if (context->request_id == request_id)
4922 retval = context->response_status;
4923 else
4924 retval = -EINVAL;
4925 spin_unlock(&hdd_context_lock);
4926 }
4927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304928 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930}
4931
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304932static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4933 struct wireless_dev *wdev,
4934 const void *data, int dataLen)
4935{
4936 int ret = 0;
4937
4938 vos_ssr_protect(__func__);
4939 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4940 vos_ssr_unprotect(__func__);
4941
4942 return ret;
4943}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304944#endif /* WLAN_FEATURE_EXTSCAN */
4945
Atul Mittal115287b2014-07-08 13:26:33 +05304946/*EXT TDLS*/
4947static const struct nla_policy
4948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4949{
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4953 {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4956
4957};
4958
4959static const struct nla_policy
4960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4961{
4962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4963
4964};
4965
4966static const struct nla_policy
4967wlan_hdd_tdls_config_state_change_policy[
4968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4969{
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304976
4977};
4978
4979static const struct nla_policy
4980wlan_hdd_tdls_config_get_status_policy[
4981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4982{
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304989
4990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304991
4992static const struct nla_policy
4993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4994{
4995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4996};
4997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304998static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304999 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305000 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305001 int data_len)
5002{
5003
5004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305007 ENTER();
5008
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305010 return -EINVAL;
5011 }
5012 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305013 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305014 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305015 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305016 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305017 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305018 return -ENOTSUPP;
5019 }
5020
5021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5022 data, data_len, wlan_hdd_mac_config)) {
5023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5024 return -EINVAL;
5025 }
5026
5027 /* Parse and fetch mac address */
5028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5030 return -EINVAL;
5031 }
5032
5033 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5034 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5035 VOS_MAC_ADDR_LAST_3_BYTES);
5036
Siddharth Bhal76972212014-10-15 16:22:51 +05305037 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5038
5039 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5041 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305042 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5044 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5045 {
5046 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5047 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5048 VOS_MAC_ADDRESS_LEN);
5049 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
Siddharth Bhal76972212014-10-15 16:22:51 +05305052 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5053 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305054 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5055 }
5056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305057 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 return 0;
5059}
5060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305061static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5062 struct wireless_dev *wdev,
5063 const void *data,
5064 int data_len)
5065{
5066 int ret = 0;
5067
5068 vos_ssr_protect(__func__);
5069 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5070 vos_ssr_unprotect(__func__);
5071
5072 return ret;
5073}
5074
5075static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305076 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305078 int data_len)
5079{
5080 u8 peer[6] = {0};
5081 struct net_device *dev = wdev->netdev;
5082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5085 eHalStatus ret;
5086 tANI_S32 state;
5087 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305088 tANI_S32 global_operating_class = 0;
5089 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305090 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305091 int retVal;
5092
5093 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305094
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305095 if (!pAdapter) {
5096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5097 return -EINVAL;
5098 }
5099
Atul Mittal115287b2014-07-08 13:26:33 +05305100 ret = wlan_hdd_validate_context(pHddCtx);
5101 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305103 return -EINVAL;
5104 }
5105 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305107 return -ENOTSUPP;
5108 }
5109 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5110 data, data_len,
5111 wlan_hdd_tdls_config_get_status_policy)) {
5112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5113 return -EINVAL;
5114 }
5115
5116 /* Parse and fetch mac address */
5117 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5119 return -EINVAL;
5120 }
5121
5122 memcpy(peer, nla_data(
5123 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5124 sizeof(peer));
5125 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5126
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305127 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305130 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305131 NLMSG_HDRLEN);
5132
5133 if (!skb) {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
5135 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5136 return -EINVAL;
5137 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 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 +05305139 reason,
5140 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305141 global_operating_class,
5142 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305143 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305144 if (nla_put_s32(skb,
5145 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5146 state) ||
5147 nla_put_s32(skb,
5148 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5149 reason) ||
5150 nla_put_s32(skb,
5151 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5152 global_operating_class) ||
5153 nla_put_s32(skb,
5154 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5155 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305156
5157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5158 goto nla_put_failure;
5159 }
5160
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305161 retVal = cfg80211_vendor_cmd_reply(skb);
5162 EXIT();
5163 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305164
5165nla_put_failure:
5166 kfree_skb(skb);
5167 return -EINVAL;
5168}
5169
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305170static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5171 struct wireless_dev *wdev,
5172 const void *data,
5173 int data_len)
5174{
5175 int ret = 0;
5176
5177 vos_ssr_protect(__func__);
5178 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5179 vos_ssr_unprotect(__func__);
5180
5181 return ret;
5182}
5183
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305184static int wlan_hdd_cfg80211_exttdls_callback(
5185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5186 const tANI_U8* mac,
5187#else
5188 tANI_U8* mac,
5189#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305190 tANI_S32 state,
5191 tANI_S32 reason,
5192 void *ctx)
5193{
5194 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305195 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 tANI_S32 global_operating_class = 0;
5197 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305198 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305200 ENTER();
5201
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305202 if (!pAdapter) {
5203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5204 return -EINVAL;
5205 }
5206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305208 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305210 return -EINVAL;
5211 }
5212
5213 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305215 return -ENOTSUPP;
5216 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305217 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5219 NULL,
5220#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305221 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5222 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5223 GFP_KERNEL);
5224
5225 if (!skb) {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
5227 FL("cfg80211_vendor_event_alloc failed"));
5228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305231 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5232 reason,
5233 state,
5234 global_operating_class,
5235 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305236 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5237 MAC_ADDR_ARRAY(mac));
5238
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305239 if (nla_put(skb,
5240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5241 VOS_MAC_ADDR_SIZE, mac) ||
5242 nla_put_s32(skb,
5243 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5244 state) ||
5245 nla_put_s32(skb,
5246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5247 reason) ||
5248 nla_put_s32(skb,
5249 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5250 channel) ||
5251 nla_put_s32(skb,
5252 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5253 global_operating_class)
5254 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5256 goto nla_put_failure;
5257 }
5258
5259 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305260 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305261 return (0);
5262
5263nla_put_failure:
5264 kfree_skb(skb);
5265 return -EINVAL;
5266}
5267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305268static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305269 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305270 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305271 int data_len)
5272{
5273 u8 peer[6] = {0};
5274 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305275 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5276 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5277 eHalStatus status;
5278 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305279 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305280 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281
5282 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305283
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305284 if (!dev) {
5285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5286 return -EINVAL;
5287 }
5288
5289 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5290 if (!pAdapter) {
5291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5292 return -EINVAL;
5293 }
5294
Atul Mittal115287b2014-07-08 13:26:33 +05305295 status = wlan_hdd_validate_context(pHddCtx);
5296 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305298 return -EINVAL;
5299 }
5300 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305302 return -ENOTSUPP;
5303 }
5304 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5305 data, data_len,
5306 wlan_hdd_tdls_config_enable_policy)) {
5307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5308 return -EINVAL;
5309 }
5310
5311 /* Parse and fetch mac address */
5312 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5314 return -EINVAL;
5315 }
5316
5317 memcpy(peer, nla_data(
5318 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5319 sizeof(peer));
5320 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5321
5322 /* Parse and fetch channel */
5323 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5325 return -EINVAL;
5326 }
5327 pReqMsg.channel = nla_get_s32(
5328 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5330
5331 /* Parse and fetch global operating class */
5332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5334 return -EINVAL;
5335 }
5336 pReqMsg.global_operating_class = nla_get_s32(
5337 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5339 pReqMsg.global_operating_class);
5340
5341 /* Parse and fetch latency ms */
5342 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5344 return -EINVAL;
5345 }
5346 pReqMsg.max_latency_ms = nla_get_s32(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5349 pReqMsg.max_latency_ms);
5350
5351 /* Parse and fetch required bandwidth kbps */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5354 return -EINVAL;
5355 }
5356
5357 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5358 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5360 pReqMsg.min_bandwidth_kbps);
5361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305362 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305363 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305364 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305365 wlan_hdd_cfg80211_exttdls_callback);
5366
5367 EXIT();
5368 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305369}
5370
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305371static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5372 struct wireless_dev *wdev,
5373 const void *data,
5374 int data_len)
5375{
5376 int ret = 0;
5377
5378 vos_ssr_protect(__func__);
5379 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5380 vos_ssr_unprotect(__func__);
5381
5382 return ret;
5383}
5384
5385static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305386 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305387 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305388 int data_len)
5389{
5390 u8 peer[6] = {0};
5391 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5393 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5394 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305396 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305397
5398 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305399
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305400 if (!dev) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5402 return -EINVAL;
5403 }
5404
5405 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406 if (!pAdapter) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5408 return -EINVAL;
5409 }
5410
Atul Mittal115287b2014-07-08 13:26:33 +05305411 status = wlan_hdd_validate_context(pHddCtx);
5412 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305414 return -EINVAL;
5415 }
5416 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305418 return -ENOTSUPP;
5419 }
5420 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5421 data, data_len,
5422 wlan_hdd_tdls_config_disable_policy)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5424 return -EINVAL;
5425 }
5426 /* Parse and fetch mac address */
5427 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5429 return -EINVAL;
5430 }
5431
5432 memcpy(peer, nla_data(
5433 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5434 sizeof(peer));
5435 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305437 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5438
5439 EXIT();
5440 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305441}
5442
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305443static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5444 struct wireless_dev *wdev,
5445 const void *data,
5446 int data_len)
5447{
5448 int ret = 0;
5449
5450 vos_ssr_protect(__func__);
5451 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5452 vos_ssr_unprotect(__func__);
5453
5454 return ret;
5455}
5456
Dasari Srinivas7875a302014-09-26 17:50:57 +05305457static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305458__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305459 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305460 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305461{
5462 struct net_device *dev = wdev->netdev;
5463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5465 struct sk_buff *skb = NULL;
5466 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305467 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305469 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305470
5471 ret = wlan_hdd_validate_context(pHddCtx);
5472 if (0 != ret)
5473 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305474 return ret;
5475 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305476 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5477 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5478 fset |= WIFI_FEATURE_INFRA;
5479 }
5480
5481 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5482 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5483 fset |= WIFI_FEATURE_INFRA_5G;
5484 }
5485
5486#ifdef WLAN_FEATURE_P2P
5487 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5488 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5489 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5490 fset |= WIFI_FEATURE_P2P;
5491 }
5492#endif
5493
5494 /* Soft-AP is supported currently by default */
5495 fset |= WIFI_FEATURE_SOFT_AP;
5496
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305497 /* HOTSPOT is a supplicant feature, enable it by default */
5498 fset |= WIFI_FEATURE_HOTSPOT;
5499
Dasari Srinivas7875a302014-09-26 17:50:57 +05305500#ifdef WLAN_FEATURE_EXTSCAN
5501 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5502 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5503 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5504 fset |= WIFI_FEATURE_EXTSCAN;
5505 }
5506#endif
5507
Dasari Srinivas7875a302014-09-26 17:50:57 +05305508 if (sme_IsFeatureSupportedByFW(NAN)) {
5509 hddLog(LOG1, FL("NAN is supported by firmware"));
5510 fset |= WIFI_FEATURE_NAN;
5511 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512
5513 /* D2D RTT is not supported currently by default */
5514 if (sme_IsFeatureSupportedByFW(RTT)) {
5515 hddLog(LOG1, FL("RTT is supported by firmware"));
5516 fset |= WIFI_FEATURE_D2AP_RTT;
5517 }
5518
5519#ifdef FEATURE_WLAN_BATCH_SCAN
5520 if (fset & WIFI_FEATURE_EXTSCAN) {
5521 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5522 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5523 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5524 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5525 fset |= WIFI_FEATURE_BATCH_SCAN;
5526 }
5527#endif
5528
5529#ifdef FEATURE_WLAN_SCAN_PNO
5530 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5531 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5532 hddLog(LOG1, FL("PNO is supported by firmware"));
5533 fset |= WIFI_FEATURE_PNO;
5534 }
5535#endif
5536
5537 /* STA+STA is supported currently by default */
5538 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5539
5540#ifdef FEATURE_WLAN_TDLS
5541 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5542 sme_IsFeatureSupportedByFW(TDLS)) {
5543 hddLog(LOG1, FL("TDLS is supported by firmware"));
5544 fset |= WIFI_FEATURE_TDLS;
5545 }
5546
5547 /* TDLS_OFFCHANNEL is not supported currently by default */
5548#endif
5549
5550#ifdef WLAN_AP_STA_CONCURRENCY
5551 /* AP+STA concurrency is supported currently by default */
5552 fset |= WIFI_FEATURE_AP_STA;
5553#endif
5554
Mukul Sharma5add0532015-08-17 15:57:47 +05305555#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5556 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5557 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5558#endif
5559
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5561 NLMSG_HDRLEN);
5562
5563 if (!skb) {
5564 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5565 return -EINVAL;
5566 }
5567 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5568
5569 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5570 hddLog(LOGE, FL("nla put fail"));
5571 goto nla_put_failure;
5572 }
5573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305574 ret = cfg80211_vendor_cmd_reply(skb);
5575 EXIT();
5576 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577
5578nla_put_failure:
5579 kfree_skb(skb);
5580 return -EINVAL;
5581}
5582
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305583static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data, int data_len)
5587{
5588 int ret = 0;
5589
5590 vos_ssr_protect(__func__);
5591 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5592 vos_ssr_unprotect(__func__);
5593
5594 return ret;
5595}
5596
5597static int
5598__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305600 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305601{
5602 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5603 uint8_t i, feature_sets, max_feature_sets;
5604 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5605 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5607 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305608
5609 ENTER();
5610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611 ret = wlan_hdd_validate_context(pHddCtx);
5612 if (0 != ret)
5613 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305614 return ret;
5615 }
5616
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5618 data, data_len, NULL)) {
5619 hddLog(LOGE, FL("Invalid ATTR"));
5620 return -EINVAL;
5621 }
5622
5623 /* Parse and fetch max feature set */
5624 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5625 hddLog(LOGE, FL("Attr max feature set size failed"));
5626 return -EINVAL;
5627 }
5628 max_feature_sets = nla_get_u32(
5629 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5630 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5631
5632 /* Fill feature combination matrix */
5633 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305634 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5635 WIFI_FEATURE_P2P;
5636
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305637 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5638 WIFI_FEATURE_SOFT_AP;
5639
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305640 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5641 WIFI_FEATURE_SOFT_AP;
5642
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305643 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5644 WIFI_FEATURE_SOFT_AP |
5645 WIFI_FEATURE_P2P;
5646
5647 /* Add more feature combinations here */
5648
5649 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5650 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5651 hddLog(LOG1, "Feature set matrix");
5652 for (i = 0; i < feature_sets; i++)
5653 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5654
5655 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5656 sizeof(u32) * feature_sets +
5657 NLMSG_HDRLEN);
5658
5659 if (reply_skb) {
5660 if (nla_put_u32(reply_skb,
5661 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5662 feature_sets) ||
5663 nla_put(reply_skb,
5664 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5665 sizeof(u32) * feature_sets, feature_set_matrix)) {
5666 hddLog(LOGE, FL("nla put fail"));
5667 kfree_skb(reply_skb);
5668 return -EINVAL;
5669 }
5670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305671 ret = cfg80211_vendor_cmd_reply(reply_skb);
5672 EXIT();
5673 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305674 }
5675 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5676 return -ENOMEM;
5677
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305678}
5679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305680static int
5681wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data, int data_len)
5684{
5685 int ret = 0;
5686
5687 vos_ssr_protect(__func__);
5688 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5689 data_len);
5690 vos_ssr_unprotect(__func__);
5691
5692 return ret;
5693}
5694
c_manjeecfd1efb2015-09-25 19:32:34 +05305695
5696static int
5697__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data, int data_len)
5700{
5701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5702 int ret;
5703 ENTER();
5704
5705 ret = wlan_hdd_validate_context(pHddCtx);
5706 if (0 != ret)
5707 {
5708 return ret;
5709 }
5710
5711 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5712 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5713 {
5714 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5715 return -EINVAL;
5716 }
5717 /*call common API for FW mem dump req*/
5718 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5719
5720 EXIT();
5721 return ret;
5722}
5723
5724/**
5725 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5726 * @wiphy: pointer to wireless wiphy structure.
5727 * @wdev: pointer to wireless_dev structure.
5728 * @data: Pointer to the NL data.
5729 * @data_len:Length of @data
5730 *
5731 * This is called when wlan driver needs to get the firmware memory dump
5732 * via vendor specific command.
5733 *
5734 * Return: 0 on success, error number otherwise.
5735 */
5736
5737static int
5738wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5739 struct wireless_dev *wdev,
5740 const void *data, int data_len)
5741
5742{
5743 int ret = 0;
5744
5745 vos_ssr_protect(__func__);
5746 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5747 data_len);
5748 vos_ssr_unprotect(__func__);
5749
5750 return ret;
5751
5752}
5753
5754
Agarwal Ashish738843c2014-09-25 12:27:56 +05305755static const struct nla_policy
5756wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5757 +1] =
5758{
5759 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5760};
5761
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305763 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305764 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305765 int data_len)
5766{
5767 struct net_device *dev = wdev->netdev;
5768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5769 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5770 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5771 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5772 eHalStatus status;
5773 u32 dfsFlag = 0;
5774
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305775 ENTER();
5776
Agarwal Ashish738843c2014-09-25 12:27:56 +05305777 status = wlan_hdd_validate_context(pHddCtx);
5778 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305779 return -EINVAL;
5780 }
5781 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5782 data, data_len,
5783 wlan_hdd_set_no_dfs_flag_config_policy)) {
5784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5785 return -EINVAL;
5786 }
5787
5788 /* Parse and fetch required bandwidth kbps */
5789 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5791 return -EINVAL;
5792 }
5793
5794 dfsFlag = nla_get_u32(
5795 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5797 dfsFlag);
5798
5799 pHddCtx->disable_dfs_flag = dfsFlag;
5800
5801 sme_disable_dfs_channel(hHal, dfsFlag);
5802 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305803
5804 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305805 return 0;
5806}
Atul Mittal115287b2014-07-08 13:26:33 +05305807
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305808static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5809 struct wireless_dev *wdev,
5810 const void *data,
5811 int data_len)
5812{
5813 int ret = 0;
5814
5815 vos_ssr_protect(__func__);
5816 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5817 vos_ssr_unprotect(__func__);
5818
5819 return ret;
5820
5821}
5822
Mukul Sharma2a271632014-10-13 14:59:01 +05305823const struct
5824nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5825{
5826 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5827 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5828};
5829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305830static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305831 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305832{
5833
5834 u8 bssid[6] = {0};
5835 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5836 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5837 eHalStatus status = eHAL_STATUS_SUCCESS;
5838 v_U32_t isFwrRoamEnabled = FALSE;
5839 int ret;
5840
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305841 ENTER();
5842
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305843 ret = wlan_hdd_validate_context(pHddCtx);
5844 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305845 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305846 }
5847
5848 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5849 data, data_len,
5850 qca_wlan_vendor_attr);
5851 if (ret){
5852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5853 return -EINVAL;
5854 }
5855
5856 /* Parse and fetch Enable flag */
5857 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5859 return -EINVAL;
5860 }
5861
5862 isFwrRoamEnabled = nla_get_u32(
5863 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5864
5865 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5866
5867 /* Parse and fetch bssid */
5868 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5870 return -EINVAL;
5871 }
5872
5873 memcpy(bssid, nla_data(
5874 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5875 sizeof(bssid));
5876 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5877
5878 //Update roaming
5879 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305880 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305881 return status;
5882}
5883
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305884static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5885 struct wireless_dev *wdev, const void *data, int data_len)
5886{
5887 int ret = 0;
5888
5889 vos_ssr_protect(__func__);
5890 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5891 vos_ssr_unprotect(__func__);
5892
5893 return ret;
5894}
5895
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305896/**
5897 * __wlan_hdd_cfg80211_setband() - set band
5898 * @wiphy: Pointer to wireless phy
5899 * @wdev: Pointer to wireless device
5900 * @data: Pointer to data
5901 * @data_len: Data length
5902 *
5903 * Return: 0 on success, negative errno on failure
5904 */
5905static int
5906__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5907 struct wireless_dev *wdev,
5908 const void *data,
5909 int data_len)
5910{
5911 struct net_device *dev = wdev->netdev;
5912 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5913 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5914 int ret;
5915 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5916 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5917
5918 ENTER();
5919
5920 ret = wlan_hdd_validate_context(hdd_ctx);
5921 if (0 != ret) {
5922 hddLog(LOGE, FL("HDD context is not valid"));
5923 return ret;
5924 }
5925
5926 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5927 policy)) {
5928 hddLog(LOGE, FL("Invalid ATTR"));
5929 return -EINVAL;
5930 }
5931
5932 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5933 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5934 return -EINVAL;
5935 }
5936
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305937 hdd_ctx->isSetBandByNL = TRUE;
5938 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305939 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305940 hdd_ctx->isSetBandByNL = FALSE;
5941
5942 EXIT();
5943 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305944}
5945
5946/**
5947 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5948 * @wiphy: wiphy structure pointer
5949 * @wdev: Wireless device structure pointer
5950 * @data: Pointer to the data received
5951 * @data_len: Length of @data
5952 *
5953 * Return: 0 on success; errno on failure
5954 */
5955static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5956 struct wireless_dev *wdev,
5957 const void *data,
5958 int data_len)
5959{
5960 int ret = 0;
5961
5962 vos_ssr_protect(__func__);
5963 ret = __wlan_hdd_cfg80211_setband(wiphy,
5964 wdev, data, data_len);
5965 vos_ssr_unprotect(__func__);
5966
5967 return ret;
5968}
5969
Sunil Duttc69bccb2014-05-26 21:30:20 +05305970const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5971{
Mukul Sharma2a271632014-10-13 14:59:01 +05305972 {
5973 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5974 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5975 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5976 WIPHY_VENDOR_CMD_NEED_NETDEV |
5977 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305978 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305979 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305980
5981 {
5982 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5983 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5984 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5985 WIPHY_VENDOR_CMD_NEED_NETDEV |
5986 WIPHY_VENDOR_CMD_NEED_RUNNING,
5987 .doit = wlan_hdd_cfg80211_nan_request
5988 },
5989
Sunil Duttc69bccb2014-05-26 21:30:20 +05305990#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5991 {
5992 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5993 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5994 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5995 WIPHY_VENDOR_CMD_NEED_NETDEV |
5996 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305997 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305998 },
5999
6000 {
6001 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6002 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6003 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6004 WIPHY_VENDOR_CMD_NEED_NETDEV |
6005 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306006 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306007 },
6008
6009 {
6010 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6011 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6012 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6013 WIPHY_VENDOR_CMD_NEED_NETDEV |
6014 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306015 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306016 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306017#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306018#ifdef WLAN_FEATURE_EXTSCAN
6019 {
6020 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6021 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6022 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6023 WIPHY_VENDOR_CMD_NEED_NETDEV |
6024 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306025 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306026 },
6027 {
6028 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6029 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6030 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6031 WIPHY_VENDOR_CMD_NEED_NETDEV |
6032 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306033 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306034 },
6035 {
6036 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6037 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6038 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6039 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306040 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306041 },
6042 {
6043 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6044 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6045 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6046 WIPHY_VENDOR_CMD_NEED_NETDEV |
6047 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306048 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306049 },
6050 {
6051 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6052 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6053 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6054 WIPHY_VENDOR_CMD_NEED_NETDEV |
6055 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306056 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306057 },
6058 {
6059 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6060 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6061 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6062 WIPHY_VENDOR_CMD_NEED_NETDEV |
6063 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306064 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306065 },
6066 {
6067 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6068 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6069 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6070 WIPHY_VENDOR_CMD_NEED_NETDEV |
6071 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306072 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306073 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306074 {
6075 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6076 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6077 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6078 WIPHY_VENDOR_CMD_NEED_NETDEV |
6079 WIPHY_VENDOR_CMD_NEED_RUNNING,
6080 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6081 },
6082 {
6083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6086 WIPHY_VENDOR_CMD_NEED_NETDEV |
6087 WIPHY_VENDOR_CMD_NEED_RUNNING,
6088 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6089 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306090#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306091/*EXT TDLS*/
6092 {
6093 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6094 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6095 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6096 WIPHY_VENDOR_CMD_NEED_NETDEV |
6097 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306098 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306099 },
6100 {
6101 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6102 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6103 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6104 WIPHY_VENDOR_CMD_NEED_NETDEV |
6105 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306106 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306107 },
6108 {
6109 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6110 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6111 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6112 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306113 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306114 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306115 {
6116 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6117 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6118 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6119 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306120 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306121 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306122 {
6123 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6124 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6125 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6126 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306127 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306128 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306129 {
6130 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6131 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6132 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6133 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306134 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306135 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306136 {
6137 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6138 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6139 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6140 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306141 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306142 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306143 {
6144 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306145 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6146 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6147 WIPHY_VENDOR_CMD_NEED_NETDEV |
6148 WIPHY_VENDOR_CMD_NEED_RUNNING,
6149 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6150 },
6151 {
6152 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306153 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6154 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6155 WIPHY_VENDOR_CMD_NEED_NETDEV |
6156 WIPHY_VENDOR_CMD_NEED_RUNNING,
6157 .doit = wlan_hdd_cfg80211_setband
6158 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306159};
6160
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006161/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306162static const
6163struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006164{
6165#ifdef FEATURE_WLAN_CH_AVOID
6166 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306167 .vendor_id = QCA_NL80211_VENDOR_ID,
6168 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006169 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306170#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6171#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6172 {
6173 /* Index = 1*/
6174 .vendor_id = QCA_NL80211_VENDOR_ID,
6175 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6176 },
6177 {
6178 /* Index = 2*/
6179 .vendor_id = QCA_NL80211_VENDOR_ID,
6180 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6181 },
6182 {
6183 /* Index = 3*/
6184 .vendor_id = QCA_NL80211_VENDOR_ID,
6185 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6186 },
6187 {
6188 /* Index = 4*/
6189 .vendor_id = QCA_NL80211_VENDOR_ID,
6190 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6191 },
6192 {
6193 /* Index = 5*/
6194 .vendor_id = QCA_NL80211_VENDOR_ID,
6195 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6196 },
6197 {
6198 /* Index = 6*/
6199 .vendor_id = QCA_NL80211_VENDOR_ID,
6200 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6201 },
6202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306203#ifdef WLAN_FEATURE_EXTSCAN
6204 {
6205 .vendor_id = QCA_NL80211_VENDOR_ID,
6206 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6207 },
6208 {
6209 .vendor_id = QCA_NL80211_VENDOR_ID,
6210 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6211 },
6212 {
6213 .vendor_id = QCA_NL80211_VENDOR_ID,
6214 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6215 },
6216 {
6217 .vendor_id = QCA_NL80211_VENDOR_ID,
6218 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6219 },
6220 {
6221 .vendor_id = QCA_NL80211_VENDOR_ID,
6222 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6223 },
6224 {
6225 .vendor_id = QCA_NL80211_VENDOR_ID,
6226 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6227 },
6228 {
6229 .vendor_id = QCA_NL80211_VENDOR_ID,
6230 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6231 },
6232 {
6233 .vendor_id = QCA_NL80211_VENDOR_ID,
6234 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6235 },
6236 {
6237 .vendor_id = QCA_NL80211_VENDOR_ID,
6238 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6239 },
6240 {
6241 .vendor_id = QCA_NL80211_VENDOR_ID,
6242 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6243 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306244 {
6245 .vendor_id = QCA_NL80211_VENDOR_ID,
6246 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6247 },
6248 {
6249 .vendor_id = QCA_NL80211_VENDOR_ID,
6250 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6251 },
6252 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6253 .vendor_id = QCA_NL80211_VENDOR_ID,
6254 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6255 },
6256 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6257 .vendor_id = QCA_NL80211_VENDOR_ID,
6258 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6259 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306260#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306261/*EXT TDLS*/
6262 {
6263 .vendor_id = QCA_NL80211_VENDOR_ID,
6264 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6265 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306266 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6267 .vendor_id = QCA_NL80211_VENDOR_ID,
6268 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6269 },
6270
Srinivas Dasari030bad32015-02-18 23:23:54 +05306271
6272 {
6273 .vendor_id = QCA_NL80211_VENDOR_ID,
6274 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6275 },
6276
Sushant Kaushik084f6592015-09-10 13:11:56 +05306277 {
6278 .vendor_id = QCA_NL80211_VENDOR_ID,
6279 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6280 }
6281
6282
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006283};
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306286 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306287 * This function is called by hdd_wlan_startup()
6288 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306289 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006290 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306291struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006292{
6293 struct wiphy *wiphy;
6294 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306295 /*
6296 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 */
6298 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6299
6300 if (!wiphy)
6301 {
6302 /* Print error and jump into err label and free the memory */
6303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6304 return NULL;
6305 }
6306
Sunil Duttc69bccb2014-05-26 21:30:20 +05306307
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 return wiphy;
6309}
6310
6311/*
6312 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306313 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 * private ioctl to change the band value
6315 */
6316int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6317{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306318 int i, j;
6319 eNVChannelEnabledType channelEnabledState;
6320
Jeff Johnsone7245742012-09-05 17:12:55 -07006321 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306322
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306323 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306325
6326 if (NULL == wiphy->bands[i])
6327 {
6328 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6329 __func__, i);
6330 continue;
6331 }
6332
6333 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6334 {
6335 struct ieee80211_supported_band *band = wiphy->bands[i];
6336
6337 channelEnabledState = vos_nv_getChannelEnabledState(
6338 band->channels[j].hw_value);
6339
6340 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6341 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306342 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306343 continue;
6344 }
6345 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6346 {
6347 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6348 continue;
6349 }
6350
6351 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6352 NV_CHANNEL_INVALID == channelEnabledState)
6353 {
6354 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6355 }
6356 else if (NV_CHANNEL_DFS == channelEnabledState)
6357 {
6358 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6359 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6360 }
6361 else
6362 {
6363 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6364 |IEEE80211_CHAN_RADAR);
6365 }
6366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 }
6368 return 0;
6369}
6370/*
6371 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306372 * This function is called by hdd_wlan_startup()
6373 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 * This function is used to initialize and register wiphy structure.
6375 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306376int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 struct wiphy *wiphy,
6378 hdd_config_t *pCfg
6379 )
6380{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306381 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306382 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6383
Jeff Johnsone7245742012-09-05 17:12:55 -07006384 ENTER();
6385
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 /* Now bind the underlying wlan device with wiphy */
6387 set_wiphy_dev(wiphy, dev);
6388
6389 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006390
Kiet Lam6c583332013-10-14 05:37:09 +05306391#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006392 /* the flag for the other case would be initialzed in
6393 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006394 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306395#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006396
Amar Singhalfddc28c2013-09-05 13:03:40 -07006397 /* This will disable updating of NL channels from passive to
6398 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6400 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6401#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006402 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306403#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006404
Amar Singhala49cbc52013-10-08 18:37:44 -07006405
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006406#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006407 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6408 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6409 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006410 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306411#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6412 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6413#else
6414 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6415#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006416#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006417
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006418#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006419 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006420#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006421 || pCfg->isFastRoamIniFeatureEnabled
6422#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006423#ifdef FEATURE_WLAN_ESE
6424 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006425#endif
6426 )
6427 {
6428 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6429 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006430#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006431#ifdef FEATURE_WLAN_TDLS
6432 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6433 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6434#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306435#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306436 if (pCfg->configPNOScanSupport)
6437 {
6438 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6439 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6440 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6441 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6442 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306443#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006444
Abhishek Singh10d85972015-04-17 10:27:23 +05306445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6446 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6447#endif
6448
Amar Singhalfddc28c2013-09-05 13:03:40 -07006449#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006450 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6451 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006452 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006453 driver need to determine what to do with both
6454 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006455
6456 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006457#else
6458 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006459#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006460
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6462
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306463 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006464
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306465 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6466
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306468 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6469 | BIT(NL80211_IFTYPE_ADHOC)
6470 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6471 | BIT(NL80211_IFTYPE_P2P_GO)
6472 | BIT(NL80211_IFTYPE_AP);
6473
6474 if (VOS_MONITOR_MODE == hdd_get_conparam())
6475 {
6476 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006478
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306479 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006480 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6482 if( pCfg->enableMCC )
6483 {
6484 /* Currently, supports up to two channels */
6485 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006486
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306487 if( !pCfg->allowMCCGODiffBI )
6488 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006489
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306490 }
6491 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6492 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006493#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306494 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006495
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 /* Before registering we need to update the ht capabilitied based
6497 * on ini values*/
6498 if( !pCfg->ShortGI20MhzEnable )
6499 {
6500 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6501 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6502 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6503 }
6504
6505 if( !pCfg->ShortGI40MhzEnable )
6506 {
6507 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6508 }
6509
6510 if( !pCfg->nChannelBondingMode5GHz )
6511 {
6512 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6513 }
6514
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306515 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306516 if (true == hdd_is_5g_supported(pHddCtx))
6517 {
6518 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6519 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306520
6521 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6522 {
6523
6524 if (NULL == wiphy->bands[i])
6525 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306526 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306527 __func__, i);
6528 continue;
6529 }
6530
6531 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6532 {
6533 struct ieee80211_supported_band *band = wiphy->bands[i];
6534
6535 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6536 {
6537 // Enable social channels for P2P
6538 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6539 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6540 else
6541 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6542 continue;
6543 }
6544 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6545 {
6546 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6547 continue;
6548 }
6549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 }
6551 /*Initialise the supported cipher suite details*/
6552 wiphy->cipher_suites = hdd_cipher_suites;
6553 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6554
6555 /*signal strength in mBm (100*dBm) */
6556 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6557
6558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306559 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006560#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006561
Sunil Duttc69bccb2014-05-26 21:30:20 +05306562 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6563 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006564 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6565 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6566
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306567 EXIT();
6568 return 0;
6569}
6570
6571/* In this function we are registering wiphy. */
6572int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6573{
6574 ENTER();
6575 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 if (0 > wiphy_register(wiphy))
6577 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306578 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6580 return -EIO;
6581 }
6582
6583 EXIT();
6584 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306585}
Jeff Johnson295189b2012-06-20 16:38:30 -07006586
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306587/* In this function we are updating channel list when,
6588 regulatory domain is FCC and country code is US.
6589 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6590 As per FCC smart phone is not a indoor device.
6591 GO should not opeate on indoor channels */
6592void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6593{
6594 int j;
6595 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6596 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6597 //Default counrtycode from NV at the time of wiphy initialization.
6598 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6599 &defaultCountryCode[0]))
6600 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006601 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306602 }
6603 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6604 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306605 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6606 {
6607 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6608 return;
6609 }
6610 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6611 {
6612 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6613 // Mark UNII -1 band channel as passive
6614 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6615 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6616 }
6617 }
6618}
6619
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306620/* This function registers for all frame which supplicant is interested in */
6621void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006622{
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6624 /* Register for all P2P action, public action etc frames */
6625 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6626
Jeff Johnsone7245742012-09-05 17:12:55 -07006627 ENTER();
6628
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 /* Right now we are registering these frame when driver is getting
6630 initialized. Once we will move to 2.6.37 kernel, in which we have
6631 frame register ops, we will move this code as a part of that */
6632 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306633 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6635
6636 /* GAS Initial Response */
6637 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6638 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306639
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 /* GAS Comeback Request */
6641 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6642 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6643
6644 /* GAS Comeback Response */
6645 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6646 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6647
6648 /* P2P Public Action */
6649 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306650 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 P2P_PUBLIC_ACTION_FRAME_SIZE );
6652
6653 /* P2P Action */
6654 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6655 (v_U8_t*)P2P_ACTION_FRAME,
6656 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006657
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306658 /* WNM BSS Transition Request frame */
6659 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6660 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6661 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006662
6663 /* WNM-Notification */
6664 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6665 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6666 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006667}
6668
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306669void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006670{
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6672 /* Register for all P2P action, public action etc frames */
6673 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6674
Jeff Johnsone7245742012-09-05 17:12:55 -07006675 ENTER();
6676
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 /* Right now we are registering these frame when driver is getting
6678 initialized. Once we will move to 2.6.37 kernel, in which we have
6679 frame register ops, we will move this code as a part of that */
6680 /* GAS Initial Request */
6681
6682 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6683 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6684
6685 /* GAS Initial Response */
6686 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6687 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306688
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 /* GAS Comeback Request */
6690 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6691 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6692
6693 /* GAS Comeback Response */
6694 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6695 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6696
6697 /* P2P Public Action */
6698 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306699 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 P2P_PUBLIC_ACTION_FRAME_SIZE );
6701
6702 /* P2P Action */
6703 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6704 (v_U8_t*)P2P_ACTION_FRAME,
6705 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006706 /* WNM-Notification */
6707 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6708 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6709 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006710}
6711
6712#ifdef FEATURE_WLAN_WAPI
6713void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306714 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006715{
6716 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6717 tCsrRoamSetKey setKey;
6718 v_BOOL_t isConnected = TRUE;
6719 int status = 0;
6720 v_U32_t roamId= 0xFF;
6721 tANI_U8 *pKeyPtr = NULL;
6722 int n = 0;
6723
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306724 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6725 __func__, hdd_device_modetoString(pAdapter->device_mode),
6726 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006727
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306728 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 setKey.keyId = key_index; // Store Key ID
6730 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6731 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6732 setKey.paeRole = 0 ; // the PAE role
6733 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6734 {
6735 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6736 }
6737 else
6738 {
6739 isConnected = hdd_connIsConnected(pHddStaCtx);
6740 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6741 }
6742 setKey.keyLength = key_Len;
6743 pKeyPtr = setKey.Key;
6744 memcpy( pKeyPtr, key, key_Len);
6745
Arif Hussain6d2a3322013-11-17 19:50:10 -08006746 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 __func__, key_Len);
6748 for (n = 0 ; n < key_Len; n++)
6749 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6750 __func__,n,setKey.Key[n]);
6751
6752 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6753 if ( isConnected )
6754 {
6755 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6756 pAdapter->sessionId, &setKey, &roamId );
6757 }
6758 if ( status != 0 )
6759 {
6760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6761 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6762 __LINE__, status );
6763 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6764 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306765 /* Need to clear any trace of key value in the memory.
6766 * Thus zero out the memory even though it is local
6767 * variable.
6768 */
6769 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006770}
6771#endif /* FEATURE_WLAN_WAPI*/
6772
6773#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 beacon_data_t **ppBeacon,
6776 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006777#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306778int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006779 beacon_data_t **ppBeacon,
6780 struct cfg80211_beacon_data *params,
6781 int dtim_period)
6782#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306783{
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 int size;
6785 beacon_data_t *beacon = NULL;
6786 beacon_data_t *old = NULL;
6787 int head_len,tail_len;
6788
Jeff Johnsone7245742012-09-05 17:12:55 -07006789 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306791 {
6792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6793 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006796
6797 old = pAdapter->sessionCtx.ap.beacon;
6798
6799 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306800 {
6801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6802 FL("session(%d) old and new heads points to NULL"),
6803 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306805 }
6806
6807 if (params->tail && !params->tail_len)
6808 {
6809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6810 FL("tail_len is zero but tail is not NULL"));
6811 return -EINVAL;
6812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006813
Jeff Johnson295189b2012-06-20 16:38:30 -07006814#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6815 /* Kernel 3.0 is not updating dtim_period for set beacon */
6816 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306817 {
6818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6819 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006822#endif
6823
6824 if(params->head)
6825 head_len = params->head_len;
6826 else
6827 head_len = old->head_len;
6828
6829 if(params->tail || !old)
6830 tail_len = params->tail_len;
6831 else
6832 tail_len = old->tail_len;
6833
6834 size = sizeof(beacon_data_t) + head_len + tail_len;
6835
6836 beacon = kzalloc(size, GFP_KERNEL);
6837
6838 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306839 {
6840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6841 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306843 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006844
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006845#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 if(params->dtim_period || !old )
6847 beacon->dtim_period = params->dtim_period;
6848 else
6849 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006850#else
6851 if(dtim_period || !old )
6852 beacon->dtim_period = dtim_period;
6853 else
6854 beacon->dtim_period = old->dtim_period;
6855#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6858 beacon->tail = beacon->head + head_len;
6859 beacon->head_len = head_len;
6860 beacon->tail_len = tail_len;
6861
6862 if(params->head) {
6863 memcpy (beacon->head,params->head,beacon->head_len);
6864 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306865 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 if(old)
6867 memcpy (beacon->head,old->head,beacon->head_len);
6868 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 if(params->tail) {
6871 memcpy (beacon->tail,params->tail,beacon->tail_len);
6872 }
6873 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306874 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006875 memcpy (beacon->tail,old->tail,beacon->tail_len);
6876 }
6877
6878 *ppBeacon = beacon;
6879
6880 kfree(old);
6881
6882 return 0;
6883
6884}
Jeff Johnson295189b2012-06-20 16:38:30 -07006885
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306886v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6888 const v_U8_t *pIes,
6889#else
6890 v_U8_t *pIes,
6891#endif
6892 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006893{
6894 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306895 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306897
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 elem_id = ptr[0];
6901 elem_len = ptr[1];
6902 left -= 2;
6903 if(elem_len > left)
6904 {
6905 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006906 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 eid,elem_len,left);
6908 return NULL;
6909 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 {
6912 return ptr;
6913 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306914
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 left -= elem_len;
6916 ptr += (elem_len + 2);
6917 }
6918 return NULL;
6919}
6920
Jeff Johnson295189b2012-06-20 16:38:30 -07006921/* Check if rate is 11g rate or not */
6922static int wlan_hdd_rate_is_11g(u8 rate)
6923{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006924 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 u8 i;
6926 for (i = 0; i < 8; i++)
6927 {
6928 if(rate == gRateArray[i])
6929 return TRUE;
6930 }
6931 return FALSE;
6932}
6933
6934/* Check for 11g rate and set proper 11g only mode */
6935static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6936 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6937{
6938 u8 i, num_rates = pIe[0];
6939
6940 pIe += 1;
6941 for ( i = 0; i < num_rates; i++)
6942 {
6943 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6944 {
6945 /* If rate set have 11g rate than change the mode to 11G */
6946 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6947 if (pIe[i] & BASIC_RATE_MASK)
6948 {
6949 /* If we have 11g rate as basic rate, it means mode
6950 is 11g only mode.
6951 */
6952 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6953 *pCheckRatesfor11g = FALSE;
6954 }
6955 }
6956 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6957 {
6958 *require_ht = TRUE;
6959 }
6960 }
6961 return;
6962}
6963
6964static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6965{
6966 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6967 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6968 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6969 u8 checkRatesfor11g = TRUE;
6970 u8 require_ht = FALSE;
6971 u8 *pIe=NULL;
6972
6973 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6974
6975 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6976 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6977 if (pIe != NULL)
6978 {
6979 pIe += 1;
6980 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6981 &pConfig->SapHw_mode);
6982 }
6983
6984 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6985 WLAN_EID_EXT_SUPP_RATES);
6986 if (pIe != NULL)
6987 {
6988
6989 pIe += 1;
6990 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6991 &pConfig->SapHw_mode);
6992 }
6993
6994 if( pConfig->channel > 14 )
6995 {
6996 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6997 }
6998
6999 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7000 WLAN_EID_HT_CAPABILITY);
7001
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307002 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 {
7004 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7005 if(require_ht)
7006 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7007 }
7008}
7009
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307010static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7011 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7012{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007013 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307014 v_U8_t *pIe = NULL;
7015 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7016
7017 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7018 pBeacon->tail, pBeacon->tail_len);
7019
7020 if (pIe)
7021 {
7022 ielen = pIe[1] + 2;
7023 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7024 {
7025 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7026 }
7027 else
7028 {
7029 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7030 return -EINVAL;
7031 }
7032 *total_ielen += ielen;
7033 }
7034 return 0;
7035}
7036
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007037static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7038 v_U8_t *genie, v_U8_t *total_ielen)
7039{
7040 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7041 int left = pBeacon->tail_len;
7042 v_U8_t *ptr = pBeacon->tail;
7043 v_U8_t elem_id, elem_len;
7044 v_U16_t ielen = 0;
7045
7046 if ( NULL == ptr || 0 == left )
7047 return;
7048
7049 while (left >= 2)
7050 {
7051 elem_id = ptr[0];
7052 elem_len = ptr[1];
7053 left -= 2;
7054 if (elem_len > left)
7055 {
7056 hddLog( VOS_TRACE_LEVEL_ERROR,
7057 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7058 elem_id, elem_len, left);
7059 return;
7060 }
7061 if (IE_EID_VENDOR == elem_id)
7062 {
7063 /* skipping the VSIE's which we don't want to include or
7064 * it will be included by existing code
7065 */
7066 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7067#ifdef WLAN_FEATURE_WFD
7068 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7069#endif
7070 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7071 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7072 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7073 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7074 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7075 {
7076 ielen = ptr[1] + 2;
7077 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7078 {
7079 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7080 *total_ielen += ielen;
7081 }
7082 else
7083 {
7084 hddLog( VOS_TRACE_LEVEL_ERROR,
7085 "IE Length is too big "
7086 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7087 elem_id, elem_len, *total_ielen);
7088 }
7089 }
7090 }
7091
7092 left -= elem_len;
7093 ptr += (elem_len + 2);
7094 }
7095 return;
7096}
7097
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007098#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007099static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7100 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007101#else
7102static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7103 struct cfg80211_beacon_data *params)
7104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007105{
7106 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307107 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007109 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007110
7111 genie = vos_mem_malloc(MAX_GENIE_LEN);
7112
7113 if(genie == NULL) {
7114
7115 return -ENOMEM;
7116 }
7117
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307118 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7119 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307121 hddLog(LOGE,
7122 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307123 ret = -EINVAL;
7124 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007125 }
7126
7127#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307128 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7129 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7130 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307131 hddLog(LOGE,
7132 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307133 ret = -EINVAL;
7134 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 }
7136#endif
7137
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307138 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7139 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307141 hddLog(LOGE,
7142 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307143 ret = -EINVAL;
7144 goto done;
7145 }
7146
7147 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7148 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007149 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007151
7152 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7153 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7154 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7155 {
7156 hddLog(LOGE,
7157 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007158 ret = -EINVAL;
7159 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 }
7161
7162 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7163 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7164 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7165 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7166 ==eHAL_STATUS_FAILURE)
7167 {
7168 hddLog(LOGE,
7169 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007170 ret = -EINVAL;
7171 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 }
7173
7174 // Added for ProResp IE
7175 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7176 {
7177 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7178 u8 probe_rsp_ie_len[3] = {0};
7179 u8 counter = 0;
7180 /* Check Probe Resp Length if it is greater then 255 then Store
7181 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7182 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7183 Store More then 255 bytes into One Variable.
7184 */
7185 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7186 {
7187 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7188 {
7189 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7190 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7191 }
7192 else
7193 {
7194 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7195 rem_probe_resp_ie_len = 0;
7196 }
7197 }
7198
7199 rem_probe_resp_ie_len = 0;
7200
7201 if (probe_rsp_ie_len[0] > 0)
7202 {
7203 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7204 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7205 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7206 probe_rsp_ie_len[0], NULL,
7207 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7208 {
7209 hddLog(LOGE,
7210 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007211 ret = -EINVAL;
7212 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 }
7214 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7215 }
7216
7217 if (probe_rsp_ie_len[1] > 0)
7218 {
7219 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7220 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7221 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7222 probe_rsp_ie_len[1], NULL,
7223 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7224 {
7225 hddLog(LOGE,
7226 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007227 ret = -EINVAL;
7228 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 }
7230 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7231 }
7232
7233 if (probe_rsp_ie_len[2] > 0)
7234 {
7235 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7236 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7237 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7238 probe_rsp_ie_len[2], NULL,
7239 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7240 {
7241 hddLog(LOGE,
7242 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007243 ret = -EINVAL;
7244 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 }
7246 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7247 }
7248
7249 if (probe_rsp_ie_len[1] == 0 )
7250 {
7251 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7252 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7253 eANI_BOOLEAN_FALSE) )
7254 {
7255 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 }
7258 }
7259
7260 if (probe_rsp_ie_len[2] == 0 )
7261 {
7262 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7263 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7264 eANI_BOOLEAN_FALSE) )
7265 {
7266 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007267 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 }
7269 }
7270
7271 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7272 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7273 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7274 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7275 == eHAL_STATUS_FAILURE)
7276 {
7277 hddLog(LOGE,
7278 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007279 ret = -EINVAL;
7280 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 }
7282 }
7283 else
7284 {
7285 // Reset WNI_CFG_PROBE_RSP Flags
7286 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7287
7288 hddLog(VOS_TRACE_LEVEL_INFO,
7289 "%s: No Probe Response IE received in set beacon",
7290 __func__);
7291 }
7292
7293 // Added for AssocResp IE
7294 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7295 {
7296 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7297 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7298 params->assocresp_ies_len, NULL,
7299 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7300 {
7301 hddLog(LOGE,
7302 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007303 ret = -EINVAL;
7304 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 }
7306
7307 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7308 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7309 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7310 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7311 == eHAL_STATUS_FAILURE)
7312 {
7313 hddLog(LOGE,
7314 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007315 ret = -EINVAL;
7316 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 }
7318 }
7319 else
7320 {
7321 hddLog(VOS_TRACE_LEVEL_INFO,
7322 "%s: No Assoc Response IE received in set beacon",
7323 __func__);
7324
7325 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7326 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7327 eANI_BOOLEAN_FALSE) )
7328 {
7329 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007330 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 }
7332 }
7333
Jeff Johnsone7245742012-09-05 17:12:55 -07007334done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307336 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007337}
Jeff Johnson295189b2012-06-20 16:38:30 -07007338
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307339/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 * FUNCTION: wlan_hdd_validate_operation_channel
7341 * called by wlan_hdd_cfg80211_start_bss() and
7342 * wlan_hdd_cfg80211_set_channel()
7343 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 * channel list.
7345 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007346VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007347{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307348
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 v_U32_t num_ch = 0;
7350 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7351 u32 indx = 0;
7352 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307353 v_U8_t fValidChannel = FALSE, count = 0;
7354 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307355
Jeff Johnson295189b2012-06-20 16:38:30 -07007356 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7357
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307358 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007359 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307360 /* Validate the channel */
7361 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307363 if ( channel == rfChannels[count].channelNum )
7364 {
7365 fValidChannel = TRUE;
7366 break;
7367 }
7368 }
7369 if (fValidChannel != TRUE)
7370 {
7371 hddLog(VOS_TRACE_LEVEL_ERROR,
7372 "%s: Invalid Channel [%d]", __func__, channel);
7373 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 }
7375 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307376 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307378 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7379 valid_ch, &num_ch))
7380 {
7381 hddLog(VOS_TRACE_LEVEL_ERROR,
7382 "%s: failed to get valid channel list", __func__);
7383 return VOS_STATUS_E_FAILURE;
7384 }
7385 for (indx = 0; indx < num_ch; indx++)
7386 {
7387 if (channel == valid_ch[indx])
7388 {
7389 break;
7390 }
7391 }
7392
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307393 if (indx >= num_ch)
7394 {
7395 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7396 {
7397 eCsrBand band;
7398 unsigned int freq;
7399
7400 sme_GetFreqBand(hHal, &band);
7401
7402 if (eCSR_BAND_5G == band)
7403 {
7404#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7405 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7406 {
7407 freq = ieee80211_channel_to_frequency(channel,
7408 IEEE80211_BAND_2GHZ);
7409 }
7410 else
7411 {
7412 freq = ieee80211_channel_to_frequency(channel,
7413 IEEE80211_BAND_5GHZ);
7414 }
7415#else
7416 freq = ieee80211_channel_to_frequency(channel);
7417#endif
7418 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7419 return VOS_STATUS_SUCCESS;
7420 }
7421 }
7422
7423 hddLog(VOS_TRACE_LEVEL_ERROR,
7424 "%s: Invalid Channel [%d]", __func__, channel);
7425 return VOS_STATUS_E_FAILURE;
7426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307428
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307430
Jeff Johnson295189b2012-06-20 16:38:30 -07007431}
7432
Viral Modi3a32cc52013-02-08 11:14:52 -08007433/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307434 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007435 * This function is used to set the channel number
7436 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307437static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007438 struct ieee80211_channel *chan,
7439 enum nl80211_channel_type channel_type
7440 )
7441{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307442 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007443 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007444 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007445 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307446 hdd_context_t *pHddCtx;
7447 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007448
7449 ENTER();
7450
7451 if( NULL == dev )
7452 {
7453 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007454 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007455 return -ENODEV;
7456 }
7457 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307458
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7460 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7461 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007462 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307463 "%s: device_mode = %s (%d) freq = %d", __func__,
7464 hdd_device_modetoString(pAdapter->device_mode),
7465 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307466
7467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7468 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307469 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007470 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307471 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007472 }
7473
7474 /*
7475 * Do freq to chan conversion
7476 * TODO: for 11a
7477 */
7478
7479 channel = ieee80211_frequency_to_channel(freq);
7480
7481 /* Check freq range */
7482 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7483 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7484 {
7485 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007487 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7488 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7489 return -EINVAL;
7490 }
7491
7492 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7493
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307494 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7495 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007496 {
7497 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7498 {
7499 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007500 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007501 return -EINVAL;
7502 }
7503 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7504 "%s: set channel to [%d] for device mode =%d",
7505 __func__, channel,pAdapter->device_mode);
7506 }
7507 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007508 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007509 )
7510 {
7511 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7512 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7513 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7514
7515 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7516 {
7517 /* Link is up then return cant set channel*/
7518 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007519 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007520 return -EINVAL;
7521 }
7522
7523 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7524 pHddStaCtx->conn_info.operationChannel = channel;
7525 pRoamProfile->ChannelInfo.ChannelList =
7526 &pHddStaCtx->conn_info.operationChannel;
7527 }
7528 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007529 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007530 )
7531 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307532 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7533 {
7534 if(VOS_STATUS_SUCCESS !=
7535 wlan_hdd_validate_operation_channel(pAdapter,channel))
7536 {
7537 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007538 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307539 return -EINVAL;
7540 }
7541 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7542 }
7543 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007544 {
7545 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7546
7547 /* If auto channel selection is configured as enable/ 1 then ignore
7548 channel set by supplicant
7549 */
7550 if ( cfg_param->apAutoChannelSelection )
7551 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307552 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7553 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007554 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307555 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7556 __func__, hdd_device_modetoString(pAdapter->device_mode),
7557 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007558 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307559 else
7560 {
7561 if(VOS_STATUS_SUCCESS !=
7562 wlan_hdd_validate_operation_channel(pAdapter,channel))
7563 {
7564 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007565 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307566 return -EINVAL;
7567 }
7568 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7569 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007570 }
7571 }
7572 else
7573 {
7574 hddLog(VOS_TRACE_LEVEL_FATAL,
7575 "%s: Invalid device mode failed to set valid channel", __func__);
7576 return -EINVAL;
7577 }
7578 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307579 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007580}
7581
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307582static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7583 struct net_device *dev,
7584 struct ieee80211_channel *chan,
7585 enum nl80211_channel_type channel_type
7586 )
7587{
7588 int ret;
7589
7590 vos_ssr_protect(__func__);
7591 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7592 vos_ssr_unprotect(__func__);
7593
7594 return ret;
7595}
7596
Jeff Johnson295189b2012-06-20 16:38:30 -07007597#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7598static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7599 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007600#else
7601static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7602 struct cfg80211_beacon_data *params,
7603 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307604 enum nl80211_hidden_ssid hidden_ssid,
7605 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007606#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007607{
7608 tsap_Config_t *pConfig;
7609 beacon_data_t *pBeacon = NULL;
7610 struct ieee80211_mgmt *pMgmt_frame;
7611 v_U8_t *pIe=NULL;
7612 v_U16_t capab_info;
7613 eCsrAuthType RSNAuthType;
7614 eCsrEncryptionType RSNEncryptType;
7615 eCsrEncryptionType mcRSNEncryptType;
7616 int status = VOS_STATUS_SUCCESS;
7617 tpWLAN_SAPEventCB pSapEventCallback;
7618 hdd_hostapd_state_t *pHostapdState;
7619 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7620 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307621 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307623 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007625 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307626 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007627 v_BOOL_t MFPCapable = VOS_FALSE;
7628 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307629 v_BOOL_t sapEnable11AC =
7630 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 ENTER();
7632
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307633 iniConfig = pHddCtx->cfg_ini;
7634
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7636
7637 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7638
7639 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7640
7641 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7642
7643 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7644
7645 //channel is already set in the set_channel Call back
7646 //pConfig->channel = pCommitConfig->channel;
7647
7648 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307649 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7651
7652 pConfig->dtim_period = pBeacon->dtim_period;
7653
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 pConfig->dtim_period);
7656
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007657 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007658 {
7659 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307661 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7662 {
7663 tANI_BOOLEAN restartNeeded;
7664 pConfig->ieee80211d = 1;
7665 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7666 sme_setRegInfo(hHal, pConfig->countryCode);
7667 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7668 }
7669 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007671 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007672 pConfig->ieee80211d = 1;
7673 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7674 sme_setRegInfo(hHal, pConfig->countryCode);
7675 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007676 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007677 else
7678 {
7679 pConfig->ieee80211d = 0;
7680 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307681 /*
7682 * If auto channel is configured i.e. channel is 0,
7683 * so skip channel validation.
7684 */
7685 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7686 {
7687 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7688 {
7689 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007690 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307691 return -EINVAL;
7692 }
7693 }
7694 else
7695 {
7696 if(1 != pHddCtx->is_dynamic_channel_range_set)
7697 {
7698 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7699 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7700 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7701 }
7702 pHddCtx->is_dynamic_channel_range_set = 0;
7703 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007704 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007705 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 {
7707 pConfig->ieee80211d = 0;
7708 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307709
7710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7711 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7712 pConfig->authType = eSAP_OPEN_SYSTEM;
7713 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7714 pConfig->authType = eSAP_SHARED_KEY;
7715 else
7716 pConfig->authType = eSAP_AUTO_SWITCH;
7717#else
7718 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7719 pConfig->authType = eSAP_OPEN_SYSTEM;
7720 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7721 pConfig->authType = eSAP_SHARED_KEY;
7722 else
7723 pConfig->authType = eSAP_AUTO_SWITCH;
7724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007725
7726 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307727
7728 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7730
7731 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7732
7733 /*Set wps station to configured*/
7734 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7735
7736 if(pIe)
7737 {
7738 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7739 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007740 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 return -EINVAL;
7742 }
7743 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7744 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007745 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 /* Check 15 bit of WPS IE as it contain information for wps state
7747 * WPS state
7748 */
7749 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7750 {
7751 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7752 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7753 {
7754 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7755 }
7756 }
7757 }
7758 else
7759 {
7760 pConfig->wps_state = SAP_WPS_DISABLED;
7761 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307762 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007763
c_hpothufe599e92014-06-16 11:38:55 +05307764 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7765 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7766 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7767 eCSR_ENCRYPT_TYPE_NONE;
7768
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 pConfig->RSNWPAReqIELength = 0;
7770 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 WLAN_EID_RSN);
7773 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307774 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7776 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7777 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307778 /* The actual processing may eventually be more extensive than
7779 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 * by the app.
7781 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307782 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7784 &RSNEncryptType,
7785 &mcRSNEncryptType,
7786 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007787 &MFPCapable,
7788 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 pConfig->pRSNWPAReqIE[1]+2,
7790 pConfig->pRSNWPAReqIE );
7791
7792 if( VOS_STATUS_SUCCESS == status )
7793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794 /* Now copy over all the security attributes you have
7795 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 * */
7797 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7798 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7799 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7800 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307801 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007802 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7804 }
7805 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307806
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7808 pBeacon->tail, pBeacon->tail_len);
7809
7810 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7811 {
7812 if (pConfig->pRSNWPAReqIE)
7813 {
7814 /*Mixed mode WPA/WPA2*/
7815 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7816 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7817 }
7818 else
7819 {
7820 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7821 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7822 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307823 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7825 &RSNEncryptType,
7826 &mcRSNEncryptType,
7827 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007828 &MFPCapable,
7829 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 pConfig->pRSNWPAReqIE[1]+2,
7831 pConfig->pRSNWPAReqIE );
7832
7833 if( VOS_STATUS_SUCCESS == status )
7834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307835 /* Now copy over all the security attributes you have
7836 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 * */
7838 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7839 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7840 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7841 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307842 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007843 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7845 }
7846 }
7847 }
7848
Jeff Johnson4416a782013-03-25 14:17:50 -07007849 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7850 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7851 return -EINVAL;
7852 }
7853
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7855
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007856#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 if (params->ssid != NULL)
7858 {
7859 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7860 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7861 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7862 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7863 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007864#else
7865 if (ssid != NULL)
7866 {
7867 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7868 pConfig->SSIDinfo.ssid.length = ssid_len;
7869 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7870 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7871 }
7872#endif
7873
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307874 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007875 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307876
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 /* default value */
7878 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7879 pConfig->num_accept_mac = 0;
7880 pConfig->num_deny_mac = 0;
7881
7882 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7883 pBeacon->tail, pBeacon->tail_len);
7884
7885 /* pIe for black list is following form:
7886 type : 1 byte
7887 length : 1 byte
7888 OUI : 4 bytes
7889 acl type : 1 byte
7890 no of mac addr in black list: 1 byte
7891 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307892 */
7893 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 {
7895 pConfig->SapMacaddr_acl = pIe[6];
7896 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007897 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307899 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7900 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7902 for (i = 0; i < pConfig->num_deny_mac; i++)
7903 {
7904 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7905 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307906 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 }
7908 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7909 pBeacon->tail, pBeacon->tail_len);
7910
7911 /* pIe for white list is following form:
7912 type : 1 byte
7913 length : 1 byte
7914 OUI : 4 bytes
7915 acl type : 1 byte
7916 no of mac addr in white list: 1 byte
7917 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307918 */
7919 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 {
7921 pConfig->SapMacaddr_acl = pIe[6];
7922 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007923 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307925 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7926 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7928 for (i = 0; i < pConfig->num_accept_mac; i++)
7929 {
7930 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7931 acl_entry++;
7932 }
7933 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307934
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7936
Jeff Johnsone7245742012-09-05 17:12:55 -07007937#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007938 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307939 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7940 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307941 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7942 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007943 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7944 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307945 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7946 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007947 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307948 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007949 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307950 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007951
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307952 /* If ACS disable and selected channel <= 14
7953 * OR
7954 * ACS enabled and ACS operating band is choosen as 2.4
7955 * AND
7956 * VHT in 2.4G Disabled
7957 * THEN
7958 * Fallback to 11N mode
7959 */
7960 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7961 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307962 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307963 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007964 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307965 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7966 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007967 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7968 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007969 }
7970#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307971
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 // ht_capab is not what the name conveys,this is used for protection bitmap
7973 pConfig->ht_capab =
7974 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7975
7976 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7977 {
7978 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7979 return -EINVAL;
7980 }
7981
7982 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7985 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307986 pConfig->obssProtEnabled =
7987 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007988
Chet Lanctot8cecea22014-02-11 19:09:36 -08007989#ifdef WLAN_FEATURE_11W
7990 pConfig->mfpCapable = MFPCapable;
7991 pConfig->mfpRequired = MFPRequired;
7992 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7993 pConfig->mfpCapable, pConfig->mfpRequired);
7994#endif
7995
Arif Hussain6d2a3322013-11-17 19:50:10 -08007996 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007998 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7999 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8000 (int)pConfig->channel);
8001 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8002 pConfig->SapHw_mode, pConfig->privacy,
8003 pConfig->authType);
8004 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8005 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8006 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8007 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008008
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 {
8011 //Bss already started. just return.
8012 //TODO Probably it should update some beacon params.
8013 hddLog( LOGE, "Bss Already started...Ignore the request");
8014 EXIT();
8015 return 0;
8016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308017
Agarwal Ashish51325b52014-06-16 16:50:49 +05308018 if (vos_max_concurrent_connections_reached()) {
8019 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8020 return -EINVAL;
8021 }
8022
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 pConfig->persona = pHostapdAdapter->device_mode;
8024
Peng Xu2446a892014-09-05 17:21:18 +05308025 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8026 if ( NULL != psmeConfig)
8027 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308028 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308029 sme_GetConfigParam(hHal, psmeConfig);
8030 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308031#ifdef WLAN_FEATURE_AP_HT40_24G
8032 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8033 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8034 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8035 {
8036 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8037 sme_UpdateConfig (hHal, psmeConfig);
8038 }
8039#endif
Peng Xu2446a892014-09-05 17:21:18 +05308040 vos_mem_free(psmeConfig);
8041 }
Peng Xuafc34e32014-09-25 13:23:55 +05308042 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308043
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 pSapEventCallback = hdd_hostapd_SAPEventCB;
8045 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8046 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8047 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008048 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 return -EINVAL;
8050 }
8051
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308052 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8054
8055 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308056
Jeff Johnson295189b2012-06-20 16:38:30 -07008057 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308058 {
8059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008060 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008061 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 VOS_ASSERT(0);
8063 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308066 /* Initialize WMM configuation */
8067 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308068 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008069
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008070#ifdef WLAN_FEATURE_P2P_DEBUG
8071 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8072 {
8073 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8074 {
8075 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8076 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008077 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008078 }
8079 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8080 {
8081 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8082 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008083 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008084 }
8085 }
8086#endif
8087
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 pHostapdState->bCommit = TRUE;
8089 EXIT();
8090
8091 return 0;
8092}
8093
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308095static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308096 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 struct beacon_parameters *params)
8098{
8099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308100 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308101 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102
8103 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308104
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308105 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8106 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8107 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8109 hdd_device_modetoString(pAdapter->device_mode),
8110 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008111
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8113 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308114 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308116 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008117 }
8118
Agarwal Ashish51325b52014-06-16 16:50:49 +05308119 if (vos_max_concurrent_connections_reached()) {
8120 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8121 return -EINVAL;
8122 }
8123
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 )
8127 {
8128 beacon_data_t *old,*new;
8129
8130 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308131
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308133 {
8134 hddLog(VOS_TRACE_LEVEL_WARN,
8135 FL("already beacon info added to session(%d)"),
8136 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308138 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008139
8140 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8141
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308142 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 {
8144 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008145 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 return -EINVAL;
8147 }
8148
8149 pAdapter->sessionCtx.ap.beacon = new;
8150
8151 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8152 }
8153
8154 EXIT();
8155 return status;
8156}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308157
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308158static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8159 struct net_device *dev,
8160 struct beacon_parameters *params)
8161{
8162 int ret;
8163
8164 vos_ssr_protect(__func__);
8165 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8166 vos_ssr_unprotect(__func__);
8167
8168 return ret;
8169}
8170
8171static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 struct net_device *dev,
8173 struct beacon_parameters *params)
8174{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308176 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8177 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308178 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008179
8180 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308181
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8183 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8184 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8186 __func__, hdd_device_modetoString(pAdapter->device_mode),
8187 pAdapter->device_mode);
8188
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308189 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8190 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308191 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008192 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308193 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008194 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308195
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308196 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308198 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 {
8200 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308201
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308205 {
8206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8207 FL("session(%d) old and new heads points to NULL"),
8208 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308210 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008211
8212 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8213
8214 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308215 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008216 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 return -EINVAL;
8218 }
8219
8220 pAdapter->sessionCtx.ap.beacon = new;
8221
8222 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8223 }
8224
8225 EXIT();
8226 return status;
8227}
8228
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308229static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8230 struct net_device *dev,
8231 struct beacon_parameters *params)
8232{
8233 int ret;
8234
8235 vos_ssr_protect(__func__);
8236 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8237 vos_ssr_unprotect(__func__);
8238
8239 return ret;
8240}
8241
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008242#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8243
8244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308245static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008247#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308248static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008249 struct net_device *dev)
8250#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008251{
8252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008253 hdd_context_t *pHddCtx = NULL;
8254 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308255 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308256 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
8258 ENTER();
8259
8260 if (NULL == pAdapter)
8261 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008263 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 return -ENODEV;
8265 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008266
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308267 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8268 TRACE_CODE_HDD_CFG80211_STOP_AP,
8269 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308270 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8271 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308272 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008273 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308274 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008275 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008276
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008277 pScanInfo = &pHddCtx->scan_info;
8278
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8280 __func__, hdd_device_modetoString(pAdapter->device_mode),
8281 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008282
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308283 ret = wlan_hdd_scan_abort(pAdapter);
8284
Girish Gowli4bf7a632014-06-12 13:42:11 +05308285 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008286 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8288 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308289
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308290 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008291 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8293 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008294
Jeff Johnsone7245742012-09-05 17:12:55 -07008295 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308296 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008297 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308298 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008299 }
8300
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308301 /* Delete all associated STAs before stopping AP/P2P GO */
8302 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308303 hdd_hostapd_stop(dev);
8304
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 )
8308 {
8309 beacon_data_t *old;
8310
8311 old = pAdapter->sessionCtx.ap.beacon;
8312
8313 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308314 {
8315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8316 FL("session(%d) beacon data points to NULL"),
8317 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008320
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008322
8323 mutex_lock(&pHddCtx->sap_lock);
8324 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8325 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008326 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008327 {
8328 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8329
8330 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8331
8332 if (!VOS_IS_STATUS_SUCCESS(status))
8333 {
8334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008335 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308337 }
8338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308340 /* BSS stopped, clear the active sessions for this device mode */
8341 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 }
8343 mutex_unlock(&pHddCtx->sap_lock);
8344
8345 if(status != VOS_STATUS_SUCCESS)
8346 {
8347 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008348 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 return -EINVAL;
8350 }
8351
Jeff Johnson4416a782013-03-25 14:17:50 -07008352 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8354 ==eHAL_STATUS_FAILURE)
8355 {
8356 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008357 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008358 }
8359
Jeff Johnson4416a782013-03-25 14:17:50 -07008360 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8362 eANI_BOOLEAN_FALSE) )
8363 {
8364 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008365 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 }
8367
8368 // Reset WNI_CFG_PROBE_RSP Flags
8369 wlan_hdd_reset_prob_rspies(pAdapter);
8370
8371 pAdapter->sessionCtx.ap.beacon = NULL;
8372 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008373#ifdef WLAN_FEATURE_P2P_DEBUG
8374 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8375 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8376 {
8377 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8378 "GO got removed");
8379 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8380 }
8381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 }
8383 EXIT();
8384 return status;
8385}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008386
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308387#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8388static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8389 struct net_device *dev)
8390{
8391 int ret;
8392
8393 vos_ssr_protect(__func__);
8394 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8395 vos_ssr_unprotect(__func__);
8396
8397 return ret;
8398}
8399#else
8400static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8401 struct net_device *dev)
8402{
8403 int ret;
8404
8405 vos_ssr_protect(__func__);
8406 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8407 vos_ssr_unprotect(__func__);
8408
8409 return ret;
8410}
8411#endif
8412
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008413#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8414
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308415static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308416 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008417 struct cfg80211_ap_settings *params)
8418{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308419 hdd_adapter_t *pAdapter;
8420 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308421 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008422
8423 ENTER();
8424
Girish Gowlib143d7a2015-02-18 19:39:55 +05308425 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008426 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308428 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308429 return -ENODEV;
8430 }
8431
8432 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8433 if (NULL == pAdapter)
8434 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308436 "%s: HDD adapter is Null", __func__);
8437 return -ENODEV;
8438 }
8439
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8441 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8442 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308443 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8444 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308446 "%s: HDD adapter magic is invalid", __func__);
8447 return -ENODEV;
8448 }
8449
8450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308451 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308452 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308453 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308454 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308455 }
8456
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308457 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8458 __func__, hdd_device_modetoString(pAdapter->device_mode),
8459 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308460
8461 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008462 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008463 )
8464 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308465 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008466
8467 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308468
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008469 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308470 {
8471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8472 FL("already beacon info added to session(%d)"),
8473 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008474 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308475 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008476
Girish Gowlib143d7a2015-02-18 19:39:55 +05308477#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8478 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8479 &new,
8480 &params->beacon);
8481#else
8482 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8483 &new,
8484 &params->beacon,
8485 params->dtim_period);
8486#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008487
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308488 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008489 {
8490 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308491 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008492 return -EINVAL;
8493 }
8494 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008496 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8497#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8498 params->channel, params->channel_type);
8499#else
8500 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8501#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008502#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008503 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308504 params->ssid_len, params->hidden_ssid,
8505 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008506 }
8507
8508 EXIT();
8509 return status;
8510}
8511
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308512static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8513 struct net_device *dev,
8514 struct cfg80211_ap_settings *params)
8515{
8516 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008517
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308518 vos_ssr_protect(__func__);
8519 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8520 vos_ssr_unprotect(__func__);
8521
8522 return ret;
8523}
8524
8525static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008526 struct net_device *dev,
8527 struct cfg80211_beacon_data *params)
8528{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308530 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308531 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008532
8533 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8536 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8537 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008538 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008539 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308540
8541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8542 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308543 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008544 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308545 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008546 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008547
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308548 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008549 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308550 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008551 {
8552 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308553
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008554 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308555
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008556 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308557 {
8558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8559 FL("session(%d) beacon data points to NULL"),
8560 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008561 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308562 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008563
8564 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8565
8566 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308567 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008568 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008569 return -EINVAL;
8570 }
8571
8572 pAdapter->sessionCtx.ap.beacon = new;
8573
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308574 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8575 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008576 }
8577
8578 EXIT();
8579 return status;
8580}
8581
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308582static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8583 struct net_device *dev,
8584 struct cfg80211_beacon_data *params)
8585{
8586 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008587
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308588 vos_ssr_protect(__func__);
8589 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8590 vos_ssr_unprotect(__func__);
8591
8592 return ret;
8593}
8594
8595#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008596
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308597static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 struct net_device *dev,
8599 struct bss_parameters *params)
8600{
8601 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308602 hdd_context_t *pHddCtx;
8603 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008604
8605 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308606
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308607 if (NULL == pAdapter)
8608 {
8609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8610 "%s: HDD adapter is Null", __func__);
8611 return -ENODEV;
8612 }
8613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308614 ret = wlan_hdd_validate_context(pHddCtx);
8615 if (0 != ret)
8616 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308617 return ret;
8618 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8620 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8621 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308622 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8623 __func__, hdd_device_modetoString(pAdapter->device_mode),
8624 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008625
8626 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308628 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 {
8630 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8631 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308632 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 {
8634 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 }
8637
8638 EXIT();
8639 return 0;
8640}
8641
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308642static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8643 struct net_device *dev,
8644 struct bss_parameters *params)
8645{
8646 int ret;
8647
8648 vos_ssr_protect(__func__);
8649 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8650 vos_ssr_unprotect(__func__);
8651
8652 return ret;
8653}
Kiet Lam10841362013-11-01 11:36:50 +05308654/* FUNCTION: wlan_hdd_change_country_code_cd
8655* to wait for contry code completion
8656*/
8657void* wlan_hdd_change_country_code_cb(void *pAdapter)
8658{
8659 hdd_adapter_t *call_back_pAdapter = pAdapter;
8660 complete(&call_back_pAdapter->change_country_code);
8661 return NULL;
8662}
8663
Jeff Johnson295189b2012-06-20 16:38:30 -07008664/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308665 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8667 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308668int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 struct net_device *ndev,
8670 enum nl80211_iftype type,
8671 u32 *flags,
8672 struct vif_params *params
8673 )
8674{
8675 struct wireless_dev *wdev;
8676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008677 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008678 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 tCsrRoamProfile *pRoamProfile = NULL;
8680 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308681 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008682 eMib_dot11DesiredBssType connectedBssType;
8683 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308684 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008685
8686 ENTER();
8687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308688 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008689 {
8690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8691 "%s: Adapter context is null", __func__);
8692 return VOS_STATUS_E_FAILURE;
8693 }
8694
8695 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8696 if (!pHddCtx)
8697 {
8698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8699 "%s: HDD context is null", __func__);
8700 return VOS_STATUS_E_FAILURE;
8701 }
8702
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308703 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8704 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8705 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308706 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308707 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308709 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 }
8711
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308712 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8713 __func__, hdd_device_modetoString(pAdapter->device_mode),
8714 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008715
Agarwal Ashish51325b52014-06-16 16:50:49 +05308716 if (vos_max_concurrent_connections_reached()) {
8717 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8718 return -EINVAL;
8719 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308720 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 wdev = ndev->ieee80211_ptr;
8722
8723#ifdef WLAN_BTAMP_FEATURE
8724 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8725 (NL80211_IFTYPE_ADHOC == type)||
8726 (NL80211_IFTYPE_AP == type)||
8727 (NL80211_IFTYPE_P2P_GO == type))
8728 {
8729 pHddCtx->isAmpAllowed = VOS_FALSE;
8730 // stop AMP traffic
8731 status = WLANBAP_StopAmp();
8732 if(VOS_STATUS_SUCCESS != status )
8733 {
8734 pHddCtx->isAmpAllowed = VOS_TRUE;
8735 hddLog(VOS_TRACE_LEVEL_FATAL,
8736 "%s: Failed to stop AMP", __func__);
8737 return -EINVAL;
8738 }
8739 }
8740#endif //WLAN_BTAMP_FEATURE
8741 /* Reset the current device mode bit mask*/
8742 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8743
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308744 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8745 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8746 (type == NL80211_IFTYPE_P2P_GO)))
8747 {
8748 /* Notify Mode change in case of concurrency.
8749 * Below function invokes TDLS teardown Functionality Since TDLS is
8750 * not Supported in case of concurrency i.e Once P2P session
8751 * is detected disable offchannel and teardown TDLS links
8752 */
8753 hddLog(LOG1,
8754 FL("Device mode = %d Interface type = %d"),
8755 pAdapter->device_mode, type);
8756 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8757 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308758
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008761 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 )
8763 {
8764 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008765 if (!pWextState)
8766 {
8767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8768 "%s: pWextState is null", __func__);
8769 return VOS_STATUS_E_FAILURE;
8770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 pRoamProfile = &pWextState->roamProfile;
8772 LastBSSType = pRoamProfile->BSSType;
8773
8774 switch (type)
8775 {
8776 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 hddLog(VOS_TRACE_LEVEL_INFO,
8779 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8780 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008781#ifdef WLAN_FEATURE_11AC
8782 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8783 {
8784 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8785 }
8786#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308787 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008788 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008790 //Check for sub-string p2p to confirm its a p2p interface
8791 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308792 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308793#ifdef FEATURE_WLAN_TDLS
8794 mutex_lock(&pHddCtx->tdls_lock);
8795 wlan_hdd_tdls_exit(pAdapter, TRUE);
8796 mutex_unlock(&pHddCtx->tdls_lock);
8797#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008798 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8799 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8800 }
8801 else
8802 {
8803 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308807
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 case NL80211_IFTYPE_ADHOC:
8809 hddLog(VOS_TRACE_LEVEL_INFO,
8810 "%s: setting interface Type to ADHOC", __func__);
8811 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8812 pRoamProfile->phyMode =
8813 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008814 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308816 hdd_set_ibss_ops( pAdapter );
8817 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308818
8819 status = hdd_sta_id_hash_attach(pAdapter);
8820 if (VOS_STATUS_SUCCESS != status) {
8821 hddLog(VOS_TRACE_LEVEL_ERROR,
8822 FL("Failed to initialize hash for IBSS"));
8823 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008824 break;
8825
8826 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 {
8829 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8830 "%s: setting interface Type to %s", __func__,
8831 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8832
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008833 //Cancel any remain on channel for GO mode
8834 if (NL80211_IFTYPE_P2P_GO == type)
8835 {
8836 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8837 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008838 if (NL80211_IFTYPE_AP == type)
8839 {
8840 /* As Loading WLAN Driver one interface being created for p2p device
8841 * address. This will take one HW STA and the max number of clients
8842 * that can connect to softAP will be reduced by one. so while changing
8843 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8844 * interface as it is not required in SoftAP mode.
8845 */
8846
8847 // Get P2P Adapter
8848 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8849
8850 if (pP2pAdapter)
8851 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308852 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308853 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008854 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8855 }
8856 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308857 //Disable IMPS & BMPS for SAP/GO
8858 if(VOS_STATUS_E_FAILURE ==
8859 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8860 {
8861 //Fail to Exit BMPS
8862 VOS_ASSERT(0);
8863 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308864
8865 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8866
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308867#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008868
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308869 /* A Mutex Lock is introduced while changing the mode to
8870 * protect the concurrent access for the Adapters by TDLS
8871 * module.
8872 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308873 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308874#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308876 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8879 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308880#ifdef FEATURE_WLAN_TDLS
8881 mutex_unlock(&pHddCtx->tdls_lock);
8882#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008883 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8884 (pConfig->apRandomBssidEnabled))
8885 {
8886 /* To meet Android requirements create a randomized
8887 MAC address of the form 02:1A:11:Fx:xx:xx */
8888 get_random_bytes(&ndev->dev_addr[3], 3);
8889 ndev->dev_addr[0] = 0x02;
8890 ndev->dev_addr[1] = 0x1A;
8891 ndev->dev_addr[2] = 0x11;
8892 ndev->dev_addr[3] |= 0xF0;
8893 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8894 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008895 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8896 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008897 }
8898
Jeff Johnson295189b2012-06-20 16:38:30 -07008899 hdd_set_ap_ops( pAdapter->dev );
8900
Kiet Lam10841362013-11-01 11:36:50 +05308901 /* This is for only SAP mode where users can
8902 * control country through ini.
8903 * P2P GO follows station country code
8904 * acquired during the STA scanning. */
8905 if((NL80211_IFTYPE_AP == type) &&
8906 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8907 {
8908 int status = 0;
8909 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8910 "%s: setting country code from INI ", __func__);
8911 init_completion(&pAdapter->change_country_code);
8912 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8913 (void *)(tSmeChangeCountryCallback)
8914 wlan_hdd_change_country_code_cb,
8915 pConfig->apCntryCode, pAdapter,
8916 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308917 eSIR_FALSE,
8918 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308919 if (eHAL_STATUS_SUCCESS == status)
8920 {
8921 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308922 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308923 &pAdapter->change_country_code,
8924 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308925 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308926 {
8927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308928 FL("SME Timed out while setting country code %ld"),
8929 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008930
8931 if (pHddCtx->isLogpInProgress)
8932 {
8933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8934 "%s: LOGP in Progress. Ignore!!!", __func__);
8935 return -EAGAIN;
8936 }
Kiet Lam10841362013-11-01 11:36:50 +05308937 }
8938 }
8939 else
8940 {
8941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008942 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308943 return -EINVAL;
8944 }
8945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 status = hdd_init_ap_mode(pAdapter);
8947 if(status != VOS_STATUS_SUCCESS)
8948 {
8949 hddLog(VOS_TRACE_LEVEL_FATAL,
8950 "%s: Error initializing the ap mode", __func__);
8951 return -EINVAL;
8952 }
8953 hdd_set_conparam(1);
8954
Nirav Shah7e3c8132015-06-22 23:51:42 +05308955 status = hdd_sta_id_hash_attach(pAdapter);
8956 if (VOS_STATUS_SUCCESS != status)
8957 {
8958 hddLog(VOS_TRACE_LEVEL_ERROR,
8959 FL("Failed to initialize hash for AP"));
8960 return -EINVAL;
8961 }
8962
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 /*interface type changed update in wiphy structure*/
8964 if(wdev)
8965 {
8966 wdev->iftype = type;
8967 pHddCtx->change_iface = type;
8968 }
8969 else
8970 {
8971 hddLog(VOS_TRACE_LEVEL_ERROR,
8972 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8973 return -EINVAL;
8974 }
8975 goto done;
8976 }
8977
8978 default:
8979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8980 __func__);
8981 return -EOPNOTSUPP;
8982 }
8983 }
8984 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 )
8987 {
8988 switch(type)
8989 {
8990 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308993
8994 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308995#ifdef FEATURE_WLAN_TDLS
8996
8997 /* A Mutex Lock is introduced while changing the mode to
8998 * protect the concurrent access for the Adapters by TDLS
8999 * module.
9000 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309001 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309002#endif
c_hpothu002231a2015-02-05 14:58:51 +05309003 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009005 //Check for sub-string p2p to confirm its a p2p interface
9006 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009007 {
9008 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9009 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9010 }
9011 else
9012 {
9013 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009015 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 hdd_set_conparam(0);
9017 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9019 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309020#ifdef FEATURE_WLAN_TDLS
9021 mutex_unlock(&pHddCtx->tdls_lock);
9022#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309023 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 if( VOS_STATUS_SUCCESS != status )
9025 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009026 /* In case of JB, for P2P-GO, only change interface will be called,
9027 * This is the right place to enable back bmps_imps()
9028 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309029 if (pHddCtx->hdd_wlan_suspended)
9030 {
9031 hdd_set_pwrparams(pHddCtx);
9032 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009033 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 goto done;
9035 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009036 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9039 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 goto done;
9041 default:
9042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9043 __func__);
9044 return -EOPNOTSUPP;
9045
9046 }
9047
9048 }
9049 else
9050 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309051 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9052 __func__, hdd_device_modetoString(pAdapter->device_mode),
9053 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 return -EOPNOTSUPP;
9055 }
9056
9057
9058 if(pRoamProfile)
9059 {
9060 if ( LastBSSType != pRoamProfile->BSSType )
9061 {
9062 /*interface type changed update in wiphy structure*/
9063 wdev->iftype = type;
9064
9065 /*the BSS mode changed, We need to issue disconnect
9066 if connected or in IBSS disconnect state*/
9067 if ( hdd_connGetConnectedBssType(
9068 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9069 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9070 {
9071 /*need to issue a disconnect to CSR.*/
9072 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9073 if( eHAL_STATUS_SUCCESS ==
9074 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9075 pAdapter->sessionId,
9076 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9077 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309078 ret = wait_for_completion_interruptible_timeout(
9079 &pAdapter->disconnect_comp_var,
9080 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9081 if (ret <= 0)
9082 {
9083 hddLog(VOS_TRACE_LEVEL_ERROR,
9084 FL("wait on disconnect_comp_var failed %ld"), ret);
9085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 }
9087 }
9088 }
9089 }
9090
9091done:
9092 /*set bitmask based on updated value*/
9093 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009094
9095 /* Only STA mode support TM now
9096 * all other mode, TM feature should be disabled */
9097 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9098 (~VOS_STA & pHddCtx->concurrency_mode) )
9099 {
9100 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9101 }
9102
Jeff Johnson295189b2012-06-20 16:38:30 -07009103#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309104 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309105 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 {
9107 //we are ok to do AMP
9108 pHddCtx->isAmpAllowed = VOS_TRUE;
9109 }
9110#endif //WLAN_BTAMP_FEATURE
9111 EXIT();
9112 return 0;
9113}
9114
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309115/*
9116 * FUNCTION: wlan_hdd_cfg80211_change_iface
9117 * wrapper function to protect the actual implementation from SSR.
9118 */
9119int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9120 struct net_device *ndev,
9121 enum nl80211_iftype type,
9122 u32 *flags,
9123 struct vif_params *params
9124 )
9125{
9126 int ret;
9127
9128 vos_ssr_protect(__func__);
9129 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9130 vos_ssr_unprotect(__func__);
9131
9132 return ret;
9133}
9134
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009135#ifdef FEATURE_WLAN_TDLS
9136static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309137 struct net_device *dev,
9138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9139 const u8 *mac,
9140#else
9141 u8 *mac,
9142#endif
9143 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009144{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009145 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009146 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309147 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309148 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309149 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309150 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009151
9152 ENTER();
9153
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309154 if (!dev) {
9155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9156 return -EINVAL;
9157 }
9158
9159 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9160 if (!pAdapter) {
9161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9162 return -EINVAL;
9163 }
9164
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309165 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009166 {
9167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9168 "Invalid arguments");
9169 return -EINVAL;
9170 }
Hoonki Lee27511902013-03-14 18:19:06 -07009171
9172 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9173 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9174 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009176 "%s: TDLS mode is disabled OR not enabled in FW."
9177 MAC_ADDRESS_STR " Request declined.",
9178 __func__, MAC_ADDR_ARRAY(mac));
9179 return -ENOTSUPP;
9180 }
9181
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009182 if (pHddCtx->isLogpInProgress)
9183 {
9184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9185 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309186 wlan_hdd_tdls_set_link_status(pAdapter,
9187 mac,
9188 eTDLS_LINK_IDLE,
9189 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009190 return -EBUSY;
9191 }
9192
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309193 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309194 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009195
9196 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009198 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9199 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309200 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009201 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009202 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309203 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009204
9205 /* in add station, we accept existing valid staId if there is */
9206 if ((0 == update) &&
9207 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9208 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009209 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009211 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009212 " link_status %d. staId %d. add station ignored.",
9213 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9214 return 0;
9215 }
9216 /* in change station, we accept only when staId is valid */
9217 if ((1 == update) &&
9218 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9219 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9220 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009222 "%s: " MAC_ADDRESS_STR
9223 " link status %d. staId %d. change station %s.",
9224 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9225 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9226 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009227 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009228
9229 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309230 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009231 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9233 "%s: " MAC_ADDRESS_STR
9234 " TDLS setup is ongoing. Request declined.",
9235 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009236 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009237 }
9238
9239 /* first to check if we reached to maximum supported TDLS peer.
9240 TODO: for now, return -EPERM looks working fine,
9241 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309242 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9243 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009244 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9246 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309247 " TDLS Max peer already connected. Request declined."
9248 " Num of peers (%d), Max allowed (%d).",
9249 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9250 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009251 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009252 }
9253 else
9254 {
9255 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309256 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009257 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009258 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9260 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9261 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009262 return -EPERM;
9263 }
9264 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009265 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309266 wlan_hdd_tdls_set_link_status(pAdapter,
9267 mac,
9268 eTDLS_LINK_CONNECTING,
9269 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009270
Jeff Johnsond75fe012013-04-06 10:53:06 -07009271 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309272 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009273 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009275 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009276 if(StaParams->htcap_present)
9277 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009279 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009281 "ht_capa->extended_capabilities: %0x",
9282 StaParams->HTCap.extendedHtCapInfo);
9283 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009285 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009287 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009288 if(StaParams->vhtcap_present)
9289 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009291 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9292 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9293 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9294 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009295 {
9296 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009298 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009300 "[%d]: %x ", i, StaParams->supported_rates[i]);
9301 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009302 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309303 else if ((1 == update) && (NULL == StaParams))
9304 {
9305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9306 "%s : update is true, but staParams is NULL. Error!", __func__);
9307 return -EPERM;
9308 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009309
9310 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9311
9312 if (!update)
9313 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309314 /*Before adding sta make sure that device exited from BMPS*/
9315 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9316 {
9317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9318 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9319 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9320 if (status != VOS_STATUS_SUCCESS) {
9321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9322 }
9323 }
9324
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309325 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009326 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309327 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309328 hddLog(VOS_TRACE_LEVEL_ERROR,
9329 FL("Failed to add TDLS peer STA. Enable Bmps"));
9330 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309331 return -EPERM;
9332 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009333 }
9334 else
9335 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309336 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009337 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309338 if (ret != eHAL_STATUS_SUCCESS) {
9339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9340 return -EPERM;
9341 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009342 }
9343
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309344 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009345 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9346
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309347 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309350 "%s: timeout waiting for tdls add station indication %ld",
9351 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009352 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009353 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309354
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009355 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9356 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009358 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009359 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009360 }
9361
9362 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009363
9364error:
Atul Mittal115287b2014-07-08 13:26:33 +05309365 wlan_hdd_tdls_set_link_status(pAdapter,
9366 mac,
9367 eTDLS_LINK_IDLE,
9368 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009369 return -EPERM;
9370
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009371}
9372#endif
9373
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309374static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309376#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9377 const u8 *mac,
9378#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309380#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 struct station_parameters *params)
9382{
9383 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309384 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309385 hdd_context_t *pHddCtx;
9386 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309388 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009389#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009390 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009391 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309392 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009393#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009394
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309395 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309396
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309397 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309398 if ((NULL == pAdapter))
9399 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309401 "invalid adapter ");
9402 return -EINVAL;
9403 }
9404
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309405 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9406 TRACE_CODE_HDD_CHANGE_STATION,
9407 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309408 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309409
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309410 ret = wlan_hdd_validate_context(pHddCtx);
9411 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309412 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309413 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309414 }
9415
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309416 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9417
9418 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009419 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9421 "invalid HDD station context");
9422 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9425
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009426 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9427 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009429 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309431 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 WLANTL_STA_AUTHENTICATED);
9433
Gopichand Nakkala29149562013-05-10 21:43:41 +05309434 if (status != VOS_STATUS_SUCCESS)
9435 {
9436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9437 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9438 return -EINVAL;
9439 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 }
9441 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009442 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9443 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309444#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009445 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9446 StaParams.capability = params->capability;
9447 StaParams.uapsd_queues = params->uapsd_queues;
9448 StaParams.max_sp = params->max_sp;
9449
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309450 /* Convert (first channel , number of channels) tuple to
9451 * the total list of channels. This goes with the assumption
9452 * that if the first channel is < 14, then the next channels
9453 * are an incremental of 1 else an incremental of 4 till the number
9454 * of channels.
9455 */
9456 if (0 != params->supported_channels_len) {
9457 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9458 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9459 {
9460 int wifi_chan_index;
9461 StaParams.supported_channels[j] = params->supported_channels[i];
9462 wifi_chan_index =
9463 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9464 no_of_channels = params->supported_channels[i+1];
9465 for(k=1; k <= no_of_channels; k++)
9466 {
9467 StaParams.supported_channels[j+1] =
9468 StaParams.supported_channels[j] + wifi_chan_index;
9469 j+=1;
9470 }
9471 }
9472 StaParams.supported_channels_len = j;
9473 }
9474 vos_mem_copy(StaParams.supported_oper_classes,
9475 params->supported_oper_classes,
9476 params->supported_oper_classes_len);
9477 StaParams.supported_oper_classes_len =
9478 params->supported_oper_classes_len;
9479
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009480 if (0 != params->ext_capab_len)
9481 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9482 sizeof(StaParams.extn_capability));
9483
9484 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009485 {
9486 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009487 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009488 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009489
9490 StaParams.supported_rates_len = params->supported_rates_len;
9491
9492 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9493 * The supported_rates array , for all the structures propogating till Add Sta
9494 * to the firmware has to be modified , if the supplicant (ieee80211) is
9495 * modified to send more rates.
9496 */
9497
9498 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9499 */
9500 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9501 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9502
9503 if (0 != StaParams.supported_rates_len) {
9504 int i = 0;
9505 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9506 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009508 "Supported Rates with Length %d", StaParams.supported_rates_len);
9509 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009511 "[%d]: %0x", i, StaParams.supported_rates[i]);
9512 }
9513
9514 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009515 {
9516 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009517 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009518 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009519
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009520 if (0 != params->ext_capab_len ) {
9521 /*Define A Macro : TODO Sunil*/
9522 if ((1<<4) & StaParams.extn_capability[3]) {
9523 isBufSta = 1;
9524 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309525 /* TDLS Channel Switching Support */
9526 if ((1<<6) & StaParams.extn_capability[3]) {
9527 isOffChannelSupported = 1;
9528 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009529 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309530 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9531 &StaParams, isBufSta,
9532 isOffChannelSupported);
9533
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309534 if (VOS_STATUS_SUCCESS != status) {
9535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9536 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9537 return -EINVAL;
9538 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009539 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9540
9541 if (VOS_STATUS_SUCCESS != status) {
9542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9543 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9544 return -EINVAL;
9545 }
9546 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009547#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309548 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009549 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 return status;
9551}
9552
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9554static int wlan_hdd_change_station(struct wiphy *wiphy,
9555 struct net_device *dev,
9556 const u8 *mac,
9557 struct station_parameters *params)
9558#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309559static int wlan_hdd_change_station(struct wiphy *wiphy,
9560 struct net_device *dev,
9561 u8 *mac,
9562 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309563#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309564{
9565 int ret;
9566
9567 vos_ssr_protect(__func__);
9568 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9569 vos_ssr_unprotect(__func__);
9570
9571 return ret;
9572}
9573
Jeff Johnson295189b2012-06-20 16:38:30 -07009574/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309575 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 * This function is used to initialize the key information
9577 */
9578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309579static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 struct net_device *ndev,
9581 u8 key_index, bool pairwise,
9582 const u8 *mac_addr,
9583 struct key_params *params
9584 )
9585#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309586static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 struct net_device *ndev,
9588 u8 key_index, const u8 *mac_addr,
9589 struct key_params *params
9590 )
9591#endif
9592{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 tCsrRoamSetKey setKey;
9595 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309596 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009597 v_U32_t roamId= 0xFF;
9598 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 hdd_hostapd_state_t *pHostapdState;
9600 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009601 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309602 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
9604 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9607 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9608 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309609 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9610 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309611 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009612 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309613 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009614 }
9615
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309616 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9617 __func__, hdd_device_modetoString(pAdapter->device_mode),
9618 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619
9620 if (CSR_MAX_NUM_KEY <= key_index)
9621 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 key_index);
9624
9625 return -EINVAL;
9626 }
9627
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009628 if (CSR_MAX_KEY_LEN < params->key_len)
9629 {
9630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9631 params->key_len);
9632
9633 return -EINVAL;
9634 }
9635
9636 hddLog(VOS_TRACE_LEVEL_INFO,
9637 "%s: called with key index = %d & key length %d",
9638 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009639
9640 /*extract key idx, key len and key*/
9641 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9642 setKey.keyId = key_index;
9643 setKey.keyLength = params->key_len;
9644 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9645
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009646 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 {
9648 case WLAN_CIPHER_SUITE_WEP40:
9649 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9650 break;
9651
9652 case WLAN_CIPHER_SUITE_WEP104:
9653 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9654 break;
9655
9656 case WLAN_CIPHER_SUITE_TKIP:
9657 {
9658 u8 *pKey = &setKey.Key[0];
9659 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9660
9661 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9662
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009663 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009664
9665 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009666 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 |--------------|----------|----------|
9668 <---16bytes---><--8bytes--><--8bytes-->
9669
9670 */
9671 /*Sme expects the 32 bytes key to be in the below order
9672
9673 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009674 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 |--------------|----------|----------|
9676 <---16bytes---><--8bytes--><--8bytes-->
9677 */
9678 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009679 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
9681 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009682 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009683
9684 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009685 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009686
9687
9688 break;
9689 }
9690
9691 case WLAN_CIPHER_SUITE_CCMP:
9692 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9693 break;
9694
9695#ifdef FEATURE_WLAN_WAPI
9696 case WLAN_CIPHER_SUITE_SMS4:
9697 {
9698 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9699 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9700 params->key, params->key_len);
9701 return 0;
9702 }
9703#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009704
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009705#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 case WLAN_CIPHER_SUITE_KRK:
9707 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9708 break;
9709#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009710
9711#ifdef WLAN_FEATURE_11W
9712 case WLAN_CIPHER_SUITE_AES_CMAC:
9713 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009714 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009715#endif
9716
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309720 status = -EOPNOTSUPP;
9721 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 }
9723
9724 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9725 __func__, setKey.encType);
9726
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009727 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9729 (!pairwise)
9730#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009731 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009732#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009733 )
9734 {
9735 /* set group key*/
9736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9737 "%s- %d: setting Broadcast key",
9738 __func__, __LINE__);
9739 setKey.keyDirection = eSIR_RX_ONLY;
9740 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9741 }
9742 else
9743 {
9744 /* set pairwise key*/
9745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9746 "%s- %d: setting pairwise key",
9747 __func__, __LINE__);
9748 setKey.keyDirection = eSIR_TX_RX;
9749 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9750 }
9751 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9752 {
9753 setKey.keyDirection = eSIR_TX_RX;
9754 /*Set the group key*/
9755 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9756 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009757
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009758 if ( 0 != status )
9759 {
9760 hddLog(VOS_TRACE_LEVEL_ERROR,
9761 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309762 status = -EINVAL;
9763 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009764 }
9765 /*Save the keys here and call sme_RoamSetKey for setting
9766 the PTK after peer joins the IBSS network*/
9767 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9768 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309769 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009770 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309771 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9772 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9773 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009775 if( pHostapdState->bssState == BSS_START )
9776 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009777 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9778 vos_status = wlan_hdd_check_ula_done(pAdapter);
9779
9780 if ( vos_status != VOS_STATUS_SUCCESS )
9781 {
9782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9783 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9784 __LINE__, vos_status );
9785
9786 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9787
9788 status = -EINVAL;
9789 goto end;
9790 }
9791
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9793
9794 if ( status != eHAL_STATUS_SUCCESS )
9795 {
9796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9797 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9798 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309799 status = -EINVAL;
9800 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 }
9802 }
9803
9804 /* Saving WEP keys */
9805 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9806 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9807 {
9808 //Save the wep key in ap context. Issue setkey after the BSS is started.
9809 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9810 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9811 }
9812 else
9813 {
9814 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009815 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9817 }
9818 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009819 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9820 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 {
9822 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9823 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9824
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9826 if (!pairwise)
9827#else
9828 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9829#endif
9830 {
9831 /* set group key*/
9832 if (pHddStaCtx->roam_info.deferKeyComplete)
9833 {
9834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9835 "%s- %d: Perform Set key Complete",
9836 __func__, __LINE__);
9837 hdd_PerformRoamSetKeyComplete(pAdapter);
9838 }
9839 }
9840
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9842
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009843 pWextState->roamProfile.Keys.defaultIndex = key_index;
9844
9845
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009846 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 params->key, params->key_len);
9848
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309849
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9851
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309852 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309854 __func__, setKey.peerMac[0], setKey.peerMac[1],
9855 setKey.peerMac[2], setKey.peerMac[3],
9856 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 setKey.keyDirection);
9858
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009859 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309860
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009861 if ( vos_status != VOS_STATUS_SUCCESS )
9862 {
9863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9865 __LINE__, vos_status );
9866
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009867 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009868
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009869 status = -EINVAL;
9870 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009871
9872 }
9873
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009874#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309875 /* The supplicant may attempt to set the PTK once pre-authentication
9876 is done. Save the key in the UMAC and include it in the ADD BSS
9877 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009878 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309879 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009880 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309881 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9882 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309883 status = 0;
9884 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309885 }
9886 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9887 {
9888 hddLog(VOS_TRACE_LEVEL_ERROR,
9889 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309890 status = -EINVAL;
9891 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009892 }
9893#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009894
9895 /* issue set key request to SME*/
9896 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9897 pAdapter->sessionId, &setKey, &roamId );
9898
9899 if ( 0 != status )
9900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309901 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9903 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309904 status = -EINVAL;
9905 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 }
9907
9908
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909 /* in case of IBSS as there was no information available about WEP keys during
9910 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309912 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9913 !( ( IW_AUTH_KEY_MGMT_802_1X
9914 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9916 )
9917 &&
9918 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9919 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9920 )
9921 )
9922 {
9923 setKey.keyDirection = eSIR_RX_ONLY;
9924 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9925
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928 __func__, setKey.peerMac[0], setKey.peerMac[1],
9929 setKey.peerMac[2], setKey.peerMac[3],
9930 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 setKey.keyDirection);
9932
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309933 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 pAdapter->sessionId, &setKey, &roamId );
9935
9936 if ( 0 != status )
9937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938 hddLog(VOS_TRACE_LEVEL_ERROR,
9939 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 __func__, status);
9941 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309942 status = -EINVAL;
9943 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009944 }
9945 }
9946 }
9947
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309948end:
9949 /* Need to clear any trace of key value in the memory.
9950 * Thus zero out the memory even though it is local
9951 * variable.
9952 */
9953 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309954 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309955 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009956}
9957
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9959static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9960 struct net_device *ndev,
9961 u8 key_index, bool pairwise,
9962 const u8 *mac_addr,
9963 struct key_params *params
9964 )
9965#else
9966static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9967 struct net_device *ndev,
9968 u8 key_index, const u8 *mac_addr,
9969 struct key_params *params
9970 )
9971#endif
9972{
9973 int ret;
9974 vos_ssr_protect(__func__);
9975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9976 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9977 mac_addr, params);
9978#else
9979 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9980 params);
9981#endif
9982 vos_ssr_unprotect(__func__);
9983
9984 return ret;
9985}
9986
Jeff Johnson295189b2012-06-20 16:38:30 -07009987/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309988 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 * This function is used to get the key information
9990 */
9991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309992static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309995 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 const u8 *mac_addr, void *cookie,
9997 void (*callback)(void *cookie, struct key_params*)
9998 )
9999#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010000static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010001 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 struct net_device *ndev,
10003 u8 key_index, const u8 *mac_addr, void *cookie,
10004 void (*callback)(void *cookie, struct key_params*)
10005 )
10006#endif
10007{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010009 hdd_wext_state_t *pWextState = NULL;
10010 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010012 hdd_context_t *pHddCtx;
10013 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010014
10015 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010017 if (NULL == pAdapter)
10018 {
10019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10020 "%s: HDD adapter is Null", __func__);
10021 return -ENODEV;
10022 }
10023
10024 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10025 ret = wlan_hdd_validate_context(pHddCtx);
10026 if (0 != ret)
10027 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010028 return ret;
10029 }
10030
10031 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10032 pRoamProfile = &(pWextState->roamProfile);
10033
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10035 __func__, hdd_device_modetoString(pAdapter->device_mode),
10036 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 memset(&params, 0, sizeof(params));
10039
10040 if (CSR_MAX_NUM_KEY <= key_index)
10041 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010045
10046 switch(pRoamProfile->EncryptionType.encryptionType[0])
10047 {
10048 case eCSR_ENCRYPT_TYPE_NONE:
10049 params.cipher = IW_AUTH_CIPHER_NONE;
10050 break;
10051
10052 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10053 case eCSR_ENCRYPT_TYPE_WEP40:
10054 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10055 break;
10056
10057 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10058 case eCSR_ENCRYPT_TYPE_WEP104:
10059 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10060 break;
10061
10062 case eCSR_ENCRYPT_TYPE_TKIP:
10063 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10064 break;
10065
10066 case eCSR_ENCRYPT_TYPE_AES:
10067 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10068 break;
10069
10070 default:
10071 params.cipher = IW_AUTH_CIPHER_NONE;
10072 break;
10073 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010074
c_hpothuaaf19692014-05-17 17:01:48 +053010075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10076 TRACE_CODE_HDD_CFG80211_GET_KEY,
10077 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010078
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10080 params.seq_len = 0;
10081 params.seq = NULL;
10082 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10083 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010084 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 return 0;
10086}
10087
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10089static int wlan_hdd_cfg80211_get_key(
10090 struct wiphy *wiphy,
10091 struct net_device *ndev,
10092 u8 key_index, bool pairwise,
10093 const u8 *mac_addr, void *cookie,
10094 void (*callback)(void *cookie, struct key_params*)
10095 )
10096#else
10097static int wlan_hdd_cfg80211_get_key(
10098 struct wiphy *wiphy,
10099 struct net_device *ndev,
10100 u8 key_index, const u8 *mac_addr, void *cookie,
10101 void (*callback)(void *cookie, struct key_params*)
10102 )
10103#endif
10104{
10105 int ret;
10106
10107 vos_ssr_protect(__func__);
10108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10109 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10110 mac_addr, cookie, callback);
10111#else
10112 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10113 callback);
10114#endif
10115 vos_ssr_unprotect(__func__);
10116
10117 return ret;
10118}
10119
Jeff Johnson295189b2012-06-20 16:38:30 -070010120/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010121 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 * This function is used to delete the key information
10123 */
10124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010125static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127 u8 key_index,
10128 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 const u8 *mac_addr
10130 )
10131#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010132static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 struct net_device *ndev,
10134 u8 key_index,
10135 const u8 *mac_addr
10136 )
10137#endif
10138{
10139 int status = 0;
10140
10141 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010142 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 //it is observed that this is invalidating peer
10144 //key index whenever re-key is done. This is affecting data link.
10145 //It should be ok to ignore del_key.
10146#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010147 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10148 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10150 tCsrRoamSetKey setKey;
10151 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010152
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 ENTER();
10154
10155 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10156 __func__,pAdapter->device_mode);
10157
10158 if (CSR_MAX_NUM_KEY <= key_index)
10159 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010160 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 key_index);
10162
10163 return -EINVAL;
10164 }
10165
10166 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10167 setKey.keyId = key_index;
10168
10169 if (mac_addr)
10170 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10171 else
10172 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10173
10174 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10175
10176 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010178 )
10179 {
10180
10181 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10183 if( pHostapdState->bssState == BSS_START)
10184 {
10185 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010186
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 if ( status != eHAL_STATUS_SUCCESS )
10188 {
10189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10190 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10191 __LINE__, status );
10192 }
10193 }
10194 }
10195 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 )
10198 {
10199 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10200
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010201 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10202
10203 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010205 __func__, setKey.peerMac[0], setKey.peerMac[1],
10206 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010207 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010208 if(pAdapter->sessionCtx.station.conn_info.connState ==
10209 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010211 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010213
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 if ( 0 != status )
10215 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010216 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 "%s: sme_RoamSetKey failure, returned %d",
10218 __func__, status);
10219 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10220 return -EINVAL;
10221 }
10222 }
10223 }
10224#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010225 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 return status;
10227}
10228
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10230static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10231 struct net_device *ndev,
10232 u8 key_index,
10233 bool pairwise,
10234 const u8 *mac_addr
10235 )
10236#else
10237static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10238 struct net_device *ndev,
10239 u8 key_index,
10240 const u8 *mac_addr
10241 )
10242#endif
10243{
10244 int ret;
10245
10246 vos_ssr_protect(__func__);
10247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10248 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10249 mac_addr);
10250#else
10251 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10252#endif
10253 vos_ssr_unprotect(__func__);
10254
10255 return ret;
10256}
10257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010259 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 * This function is used to set the default tx key index
10261 */
10262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010263static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 struct net_device *ndev,
10265 u8 key_index,
10266 bool unicast, bool multicast)
10267#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010268static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 struct net_device *ndev,
10270 u8 key_index)
10271#endif
10272{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010273 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010274 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010275 hdd_wext_state_t *pWextState;
10276 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010277 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010278
10279 ENTER();
10280
Gopichand Nakkala29149562013-05-10 21:43:41 +053010281 if ((NULL == pAdapter))
10282 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010284 "invalid adapter");
10285 return -EINVAL;
10286 }
10287
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10289 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10290 pAdapter->sessionId, key_index));
10291
Gopichand Nakkala29149562013-05-10 21:43:41 +053010292 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10293 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10294
10295 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10296 {
10297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10298 "invalid Wext state or HDD context");
10299 return -EINVAL;
10300 }
10301
Arif Hussain6d2a3322013-11-17 19:50:10 -080010302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010304
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 if (CSR_MAX_NUM_KEY <= key_index)
10306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010308 key_index);
10309
10310 return -EINVAL;
10311 }
10312
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010313 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10314 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010315 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010316 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010317 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010322 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010324 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010325 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010327 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010328 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010329 {
10330 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 tCsrRoamSetKey setKey;
10334 v_U32_t roamId= 0xFF;
10335 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010336
10337 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010338 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010339
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 Keys->defaultIndex = (u8)key_index;
10341 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10342 setKey.keyId = key_index;
10343 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010344
10345 vos_mem_copy(&setKey.Key[0],
10346 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010347 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010348
Gopichand Nakkala29149562013-05-10 21:43:41 +053010349 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010350
10351 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 &pHddStaCtx->conn_info.bssId[0],
10353 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010354
Gopichand Nakkala29149562013-05-10 21:43:41 +053010355 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10356 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10357 eCSR_ENCRYPT_TYPE_WEP104)
10358 {
10359 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10360 even though ap is configured for WEP-40 encryption. In this canse the key length
10361 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10362 type(104) and switching encryption type to 40*/
10363 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10364 eCSR_ENCRYPT_TYPE_WEP40;
10365 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10366 eCSR_ENCRYPT_TYPE_WEP40;
10367 }
10368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010369 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010371
Jeff Johnson295189b2012-06-20 16:38:30 -070010372 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010373 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 if ( 0 != status )
10377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010378 hddLog(VOS_TRACE_LEVEL_ERROR,
10379 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 status);
10381 return -EINVAL;
10382 }
10383 }
10384 }
10385
10386 /* In SoftAp mode setting key direction for default mode */
10387 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10388 {
10389 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10390 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10391 (eCSR_ENCRYPT_TYPE_AES !=
10392 pWextState->roamProfile.EncryptionType.encryptionType[0])
10393 )
10394 {
10395 /* Saving key direction for default key index to TX default */
10396 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10397 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10398 }
10399 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010400 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 return status;
10402}
10403
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10405static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10406 struct net_device *ndev,
10407 u8 key_index,
10408 bool unicast, bool multicast)
10409#else
10410static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10411 struct net_device *ndev,
10412 u8 key_index)
10413#endif
10414{
10415 int ret;
10416 vos_ssr_protect(__func__);
10417#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10418 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10419 multicast);
10420#else
10421 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10422#endif
10423 vos_ssr_unprotect(__func__);
10424
10425 return ret;
10426}
10427
Jeff Johnson295189b2012-06-20 16:38:30 -070010428/*
10429 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10430 * This function is used to inform the BSS details to nl80211 interface.
10431 */
10432static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10433 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10434{
10435 struct net_device *dev = pAdapter->dev;
10436 struct wireless_dev *wdev = dev->ieee80211_ptr;
10437 struct wiphy *wiphy = wdev->wiphy;
10438 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10439 int chan_no;
10440 int ie_length;
10441 const char *ie;
10442 unsigned int freq;
10443 struct ieee80211_channel *chan;
10444 int rssi = 0;
10445 struct cfg80211_bss *bss = NULL;
10446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 if( NULL == pBssDesc )
10448 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010449 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 return bss;
10451 }
10452
10453 chan_no = pBssDesc->channelId;
10454 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10455 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10456
10457 if( NULL == ie )
10458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010459 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 return bss;
10461 }
10462
10463#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10464 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10465 {
10466 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10467 }
10468 else
10469 {
10470 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10471 }
10472#else
10473 freq = ieee80211_channel_to_frequency(chan_no);
10474#endif
10475
10476 chan = __ieee80211_get_channel(wiphy, freq);
10477
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010478 if (!chan) {
10479 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10480 return NULL;
10481 }
10482
Abhishek Singhaee43942014-06-16 18:55:47 +053010483 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010484
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010485 return cfg80211_inform_bss(wiphy, chan,
10486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10487 CFG80211_BSS_FTYPE_UNKNOWN,
10488#endif
10489 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010490 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 pBssDesc->capabilityInfo,
10492 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010493 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010494}
10495
10496
10497
10498/*
10499 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10500 * This function is used to inform the BSS details to nl80211 interface.
10501 */
10502struct cfg80211_bss*
10503wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10504 tSirBssDescription *bss_desc
10505 )
10506{
10507 /*
10508 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10509 already exists in bss data base of cfg80211 for that particular BSS ID.
10510 Using cfg80211_inform_bss_frame to update the bss entry instead of
10511 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10512 now there is no possibility to get the mgmt(probe response) frame from PE,
10513 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10514 cfg80211_inform_bss_frame.
10515 */
10516 struct net_device *dev = pAdapter->dev;
10517 struct wireless_dev *wdev = dev->ieee80211_ptr;
10518 struct wiphy *wiphy = wdev->wiphy;
10519 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010520#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10521 qcom_ie_age *qie_age = NULL;
10522 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10523#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010525#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 const char *ie =
10527 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10528 unsigned int freq;
10529 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010530 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 struct cfg80211_bss *bss_status = NULL;
10532 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10533 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010534 hdd_context_t *pHddCtx;
10535 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010536#ifdef WLAN_OPEN_SOURCE
10537 struct timespec ts;
10538#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010540
Wilson Yangf80a0542013-10-07 13:02:37 -070010541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10542 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010543 if (0 != status)
10544 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010545 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010546 }
10547
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010548 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010549 if (!mgmt)
10550 {
10551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10552 "%s: memory allocation failed ", __func__);
10553 return NULL;
10554 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010555
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010557
10558#ifdef WLAN_OPEN_SOURCE
10559 /* Android does not want the timestamp from the frame.
10560 Instead it wants a monotonic increasing value */
10561 get_monotonic_boottime(&ts);
10562 mgmt->u.probe_resp.timestamp =
10563 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10564#else
10565 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10567 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010568
10569#endif
10570
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10572 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010573
10574#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10575 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10576 /* Assuming this is the last IE, copy at the end */
10577 ie_length -=sizeof(qcom_ie_age);
10578 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10579 qie_age->element_id = QCOM_VENDOR_IE_ID;
10580 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10581 qie_age->oui_1 = QCOM_OUI1;
10582 qie_age->oui_2 = QCOM_OUI2;
10583 qie_age->oui_3 = QCOM_OUI3;
10584 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10585 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10586#endif
10587
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010589 if (bss_desc->fProbeRsp)
10590 {
10591 mgmt->frame_control |=
10592 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10593 }
10594 else
10595 {
10596 mgmt->frame_control |=
10597 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10598 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010599
10600#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010601 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10603 {
10604 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10605 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010606 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010607 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10608
10609 {
10610 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10611 }
10612 else
10613 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010614 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10615 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010616 kfree(mgmt);
10617 return NULL;
10618 }
10619#else
10620 freq = ieee80211_channel_to_frequency(chan_no);
10621#endif
10622 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010623 /*when the band is changed on the fly using the GUI, three things are done
10624 * 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)
10625 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10626 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10627 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10628 * and discards the channels correponding to previous band and calls back with zero bss results.
10629 * 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
10630 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10631 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10632 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10633 * So drop the bss and continue to next bss.
10634 */
10635 if(chan == NULL)
10636 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010638 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010639 return NULL;
10640 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010641 /*To keep the rssi icon of the connected AP in the scan window
10642 *and the rssi icon of the wireless networks in sync
10643 * */
10644 if (( eConnectionState_Associated ==
10645 pAdapter->sessionCtx.station.conn_info.connState ) &&
10646 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10647 pAdapter->sessionCtx.station.conn_info.bssId,
10648 WNI_CFG_BSSID_LEN)) &&
10649 (pHddCtx->hdd_wlan_suspended == FALSE))
10650 {
10651 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10652 rssi = (pAdapter->rssi * 100);
10653 }
10654 else
10655 {
10656 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10657 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
Nirav Shah20ac06f2013-12-12 18:14:06 +053010659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010660 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10661 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10664 frame_len, rssi, GFP_KERNEL);
10665 kfree(mgmt);
10666 return bss_status;
10667}
10668
10669/*
10670 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10671 * This function is used to update the BSS data base of CFG8011
10672 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010673struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 tCsrRoamInfo *pRoamInfo
10675 )
10676{
10677 tCsrRoamConnectedProfile roamProfile;
10678 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10679 struct cfg80211_bss *bss = NULL;
10680
10681 ENTER();
10682
10683 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10684 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10685
10686 if (NULL != roamProfile.pBssDesc)
10687 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010688 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10689 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010690
10691 if (NULL == bss)
10692 {
10693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10694 __func__);
10695 }
10696
10697 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10698 }
10699 else
10700 {
10701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10702 __func__);
10703 }
10704 return bss;
10705}
10706
10707/*
10708 * FUNCTION: wlan_hdd_cfg80211_update_bss
10709 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010710static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10711 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010712 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010713{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010714 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010715 tCsrScanResultInfo *pScanResult;
10716 eHalStatus status = 0;
10717 tScanResultHandle pResult;
10718 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010719 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010720 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10724 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10725 NO_SESSION, pAdapter->sessionId));
10726
Wilson Yangf80a0542013-10-07 13:02:37 -070010727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10728
10729 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10732 "%s:LOGP in Progress. Ignore!!!",__func__);
10733 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 }
10735
Wilson Yangf80a0542013-10-07 13:02:37 -070010736
10737 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010738 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010739 {
10740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10741 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10742 return VOS_STATUS_E_PERM;
10743 }
10744
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010745 if (pAdapter->request != NULL)
10746 {
10747 if ((pAdapter->request->n_ssids == 1)
10748 && (pAdapter->request->ssids != NULL)
10749 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10750 is_p2p_scan = true;
10751 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 /*
10753 * start getting scan results and populate cgf80211 BSS database
10754 */
10755 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10756
10757 /* no scan results */
10758 if (NULL == pResult)
10759 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10761 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010762 wlan_hdd_get_frame_logs(pAdapter,
10763 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010764 return status;
10765 }
10766
10767 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10768
10769 while (pScanResult)
10770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010771 /*
10772 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10773 * entry already exists in bss data base of cfg80211 for that
10774 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10775 * bss entry instead of cfg80211_inform_bss, But this call expects
10776 * mgmt packet as input. As of now there is no possibility to get
10777 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 * ieee80211_mgmt(probe response) and passing to c
10779 * fg80211_inform_bss_frame.
10780 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010781 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10782 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10783 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010784 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10785 continue; //Skip the non p2p bss entries
10786 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010787 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10788 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789
Jeff Johnson295189b2012-06-20 16:38:30 -070010790
10791 if (NULL == bss_status)
10792 {
10793 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010794 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 }
10796 else
10797 {
Yue Maf49ba872013-08-19 12:04:25 -070010798 cfg80211_put_bss(
10799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10800 wiphy,
10801#endif
10802 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 }
10804
10805 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10806 }
10807
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010808 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010809 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010810 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010811}
10812
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010813void
10814hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10815{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010816 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010817 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010818} /****** end hddPrintMacAddr() ******/
10819
10820void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010821hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010822{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010823 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010824 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010825 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10826 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10827 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010828} /****** end hddPrintPmkId() ******/
10829
10830//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10831//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10832
10833//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10834//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10835
10836#define dump_bssid(bssid) \
10837 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010838 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10839 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010840 }
10841
10842#define dump_pmkid(pMac, pmkid) \
10843 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010844 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10845 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010846 }
10847
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010848#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010849/*
10850 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10851 * This function is used to notify the supplicant of a new PMKSA candidate.
10852 */
10853int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010854 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010855 int index, bool preauth )
10856{
Jeff Johnsone7245742012-09-05 17:12:55 -070010857#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010858 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010859 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010860
10861 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010862 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010863
10864 if( NULL == pRoamInfo )
10865 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010866 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010867 return -EINVAL;
10868 }
10869
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010870 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10871 {
10872 dump_bssid(pRoamInfo->bssid);
10873 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010874 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010875 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010876#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010877 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010878}
10879#endif //FEATURE_WLAN_LFR
10880
Yue Maef608272013-04-08 23:09:17 -070010881#ifdef FEATURE_WLAN_LFR_METRICS
10882/*
10883 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10884 * 802.11r/LFR metrics reporting function to report preauth initiation
10885 *
10886 */
10887#define MAX_LFR_METRICS_EVENT_LENGTH 100
10888VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10889 tCsrRoamInfo *pRoamInfo)
10890{
10891 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10892 union iwreq_data wrqu;
10893
10894 ENTER();
10895
10896 if (NULL == pAdapter)
10897 {
10898 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10899 return VOS_STATUS_E_FAILURE;
10900 }
10901
10902 /* create the event */
10903 memset(&wrqu, 0, sizeof(wrqu));
10904 memset(metrics_notification, 0, sizeof(metrics_notification));
10905
10906 wrqu.data.pointer = metrics_notification;
10907 wrqu.data.length = scnprintf(metrics_notification,
10908 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10909 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10910
10911 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10912
10913 EXIT();
10914
10915 return VOS_STATUS_SUCCESS;
10916}
10917
10918/*
10919 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10920 * 802.11r/LFR metrics reporting function to report preauth completion
10921 * or failure
10922 */
10923VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10924 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10925{
10926 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10927 union iwreq_data wrqu;
10928
10929 ENTER();
10930
10931 if (NULL == pAdapter)
10932 {
10933 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10934 return VOS_STATUS_E_FAILURE;
10935 }
10936
10937 /* create the event */
10938 memset(&wrqu, 0, sizeof(wrqu));
10939 memset(metrics_notification, 0, sizeof(metrics_notification));
10940
10941 scnprintf(metrics_notification, sizeof(metrics_notification),
10942 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10943 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10944
10945 if (1 == preauth_status)
10946 strncat(metrics_notification, " TRUE", 5);
10947 else
10948 strncat(metrics_notification, " FALSE", 6);
10949
10950 wrqu.data.pointer = metrics_notification;
10951 wrqu.data.length = strlen(metrics_notification);
10952
10953 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10954
10955 EXIT();
10956
10957 return VOS_STATUS_SUCCESS;
10958}
10959
10960/*
10961 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10962 * 802.11r/LFR metrics reporting function to report handover initiation
10963 *
10964 */
10965VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10966 tCsrRoamInfo *pRoamInfo)
10967{
10968 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10969 union iwreq_data wrqu;
10970
10971 ENTER();
10972
10973 if (NULL == pAdapter)
10974 {
10975 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10976 return VOS_STATUS_E_FAILURE;
10977 }
10978
10979 /* create the event */
10980 memset(&wrqu, 0, sizeof(wrqu));
10981 memset(metrics_notification, 0, sizeof(metrics_notification));
10982
10983 wrqu.data.pointer = metrics_notification;
10984 wrqu.data.length = scnprintf(metrics_notification,
10985 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10986 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10987
10988 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10989
10990 EXIT();
10991
10992 return VOS_STATUS_SUCCESS;
10993}
10994#endif
10995
Jeff Johnson295189b2012-06-20 16:38:30 -070010996/*
10997 * FUNCTION: hdd_cfg80211_scan_done_callback
10998 * scanning callback function, called after finishing scan
10999 *
11000 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011001static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011002 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11003{
11004 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011005 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011007 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 struct cfg80211_scan_request *req = NULL;
11009 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011010 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011011 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011012 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011013 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011014
11015 ENTER();
11016
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011017 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011018 if (NULL == pHddCtx) {
11019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011020 goto allow_suspend;
11021 }
11022
11023 pScanInfo = &pHddCtx->scan_info;
11024
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 hddLog(VOS_TRACE_LEVEL_INFO,
11026 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011027 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 __func__, halHandle, pContext, (int) scanId, (int) status);
11029
Kiet Lamac06e2c2013-10-23 16:25:07 +053011030 pScanInfo->mScanPendingCounter = 0;
11031
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011033 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 &pScanInfo->scan_req_completion_event,
11035 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011036 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011038 hddLog(VOS_TRACE_LEVEL_ERROR,
11039 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011041 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 }
11043
Yue Maef608272013-04-08 23:09:17 -070011044 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 {
11046 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011047 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 }
11049
11050 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011051 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 {
11053 hddLog(VOS_TRACE_LEVEL_INFO,
11054 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011055 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 (int) scanId);
11057 }
11058
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011059 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 pAdapter);
11061
11062 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011064
11065
11066 /* If any client wait scan result through WEXT
11067 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011068 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 {
11070 /* The other scan request waiting for current scan finish
11071 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011072 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011074 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 }
11076 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011077 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011078 {
11079 struct net_device *dev = pAdapter->dev;
11080 union iwreq_data wrqu;
11081 int we_event;
11082 char *msg;
11083
11084 memset(&wrqu, '\0', sizeof(wrqu));
11085 we_event = SIOCGIWSCAN;
11086 msg = NULL;
11087 wireless_send_event(dev, we_event, &wrqu, msg);
11088 }
11089 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011090 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011091
11092 /* Get the Scan Req */
11093 req = pAdapter->request;
11094
11095 if (!req)
11096 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011097 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011098 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011099 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 }
11101
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011103 /* Scan is no longer pending */
11104 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011105
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011106 /* last_scan_timestamp is used to decide if new scan
11107 * is needed or not on station interface. If last station
11108 * scan time and new station scan time is less then
11109 * last_scan_timestamp ; driver will return cached scan.
11110 */
11111 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11112 {
11113 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11114
11115 if ( req->n_channels )
11116 {
11117 for (i = 0; i < req->n_channels ; i++ )
11118 {
11119 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11120 }
11121 /* store no of channel scanned */
11122 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11123 }
11124
11125 }
11126
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011127 /*
11128 * cfg80211_scan_done informing NL80211 about completion
11129 * of scanning
11130 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011131 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11132 {
11133 aborted = true;
11134 }
11135 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011136 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011137
Siddharth Bhal76972212014-10-15 16:22:51 +053011138 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11139 /* Generate new random mac addr for next scan */
11140 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11141 hdd_processSpoofMacAddrRequest(pHddCtx);
11142 }
11143
Jeff Johnsone7245742012-09-05 17:12:55 -070011144allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011145 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011146 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011147
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011148 /* Acquire wakelock to handle the case where APP's tries to suspend
11149 * immediatly after the driver gets connect request(i.e after scan)
11150 * from supplicant, this result in app's is suspending and not able
11151 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011152 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011153
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011154#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011155 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011156#endif
11157
Jeff Johnson295189b2012-06-20 16:38:30 -070011158 EXIT();
11159 return 0;
11160}
11161
11162/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011163 * FUNCTION: hdd_isConnectionInProgress
11164 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011165 *
11166 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011167v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011168{
11169 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11170 hdd_station_ctx_t *pHddStaCtx = NULL;
11171 hdd_adapter_t *pAdapter = NULL;
11172 VOS_STATUS status = 0;
11173 v_U8_t staId = 0;
11174 v_U8_t *staMac = NULL;
11175
c_hpothu9b781ba2013-12-30 20:57:45 +053011176 if (TRUE == pHddCtx->btCoexModeSet)
11177 {
11178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011179 FL("BTCoex Mode operation in progress"));
11180 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011181 }
11182
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011183 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11184
11185 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11186 {
11187 pAdapter = pAdapterNode->pAdapter;
11188
11189 if( pAdapter )
11190 {
11191 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011192 "%s: Adapter with device mode %s (%d) exists",
11193 __func__, hdd_device_modetoString(pAdapter->device_mode),
11194 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011195 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011196 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11197 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11198 (eConnectionState_Connecting ==
11199 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11200 {
11201 hddLog(VOS_TRACE_LEVEL_ERROR,
11202 "%s: %p(%d) Connection is in progress", __func__,
11203 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11204 return VOS_TRUE;
11205 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011206 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011207 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011208 {
11209 hddLog(VOS_TRACE_LEVEL_ERROR,
11210 "%s: %p(%d) Reassociation is in progress", __func__,
11211 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11212 return VOS_TRUE;
11213 }
11214 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011215 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11216 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011217 {
11218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11219 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011220 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011221 {
11222 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11223 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011224 "%s: client " MAC_ADDRESS_STR
11225 " is in the middle of WPS/EAPOL exchange.", __func__,
11226 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011227 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011228 }
11229 }
11230 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11231 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11232 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011233 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11234 ptSapContext pSapCtx = NULL;
11235 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11236 if(pSapCtx == NULL){
11237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11238 FL("psapCtx is NULL"));
11239 return VOS_FALSE;
11240 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011241 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11242 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011243 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11244 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011245 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011246 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011247
11248 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011249 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11250 "middle of WPS/EAPOL exchange.", __func__,
11251 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011252 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011253 }
11254 }
11255 }
11256 }
11257 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11258 pAdapterNode = pNext;
11259 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011260 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011261}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011262
11263/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011264 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 * this scan respond to scan trigger and update cfg80211 scan database
11266 * later, scan dump command can be used to recieve scan results
11267 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011268int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011269#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11270 struct net_device *dev,
11271#endif
11272 struct cfg80211_scan_request *request)
11273{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011274 hdd_adapter_t *pAdapter = NULL;
11275 hdd_context_t *pHddCtx = NULL;
11276 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011277 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 tCsrScanRequest scanRequest;
11279 tANI_U8 *channelList = NULL, i;
11280 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011281 int status;
11282 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011284 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011285 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011286 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011287 v_S7_t rssi=0;
11288 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011289
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11291 struct net_device *dev = NULL;
11292 if (NULL == request)
11293 {
11294 hddLog(VOS_TRACE_LEVEL_ERROR,
11295 "%s: scan req param null", __func__);
11296 return -EINVAL;
11297 }
11298 dev = request->wdev->netdev;
11299#endif
11300
11301 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11302 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11303 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11304
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 ENTER();
11306
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11308 __func__, hdd_device_modetoString(pAdapter->device_mode),
11309 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011310
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011312 if (0 != status)
11313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011314 return status;
11315 }
11316
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011317 if (NULL == pwextBuf)
11318 {
11319 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11320 __func__);
11321 return -EIO;
11322 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011323 cfg_param = pHddCtx->cfg_ini;
11324 pScanInfo = &pHddCtx->scan_info;
11325
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011326 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11327 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11328 {
11329 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11330 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11331 }
11332
Jeff Johnson295189b2012-06-20 16:38:30 -070011333#ifdef WLAN_BTAMP_FEATURE
11334 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011335 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011337 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 "%s: No scanning when AMP is on", __func__);
11339 return -EOPNOTSUPP;
11340 }
11341#endif
11342 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011343 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011345 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011346 "%s: Not scanning on device_mode = %s (%d)",
11347 __func__, hdd_device_modetoString(pAdapter->device_mode),
11348 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 return -EOPNOTSUPP;
11350 }
11351
11352 if (TRUE == pScanInfo->mScanPending)
11353 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011354 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11355 {
11356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11357 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011358 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 }
11360
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011361 // Don't allow scan if PNO scan is going on.
11362 if (pHddCtx->isPnoEnable)
11363 {
11364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11365 FL("pno scan in progress"));
11366 return -EBUSY;
11367 }
11368
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011369 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011370 //Channel and action frame is pending
11371 //Otherwise Cancel Remain On Channel and allow Scan
11372 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011373 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011374 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011376 return -EBUSY;
11377 }
11378
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11380 {
11381 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011382 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11386 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011387 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 "%s: MAX TM Level Scan not allowed", __func__);
11389 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011390 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 }
11392 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11393
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011394 /* Check if scan is allowed at this point of time.
11395 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011396 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011397 {
11398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11399 return -EBUSY;
11400 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011401
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11403
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011404 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11405 * Becasue of this, driver is assuming that this is not wildcard scan and so
11406 * is not aging out the scan results.
11407 */
11408 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011410 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011412
11413 if ((request->ssids) && (0 < request->n_ssids))
11414 {
11415 tCsrSSIDInfo *SsidInfo;
11416 int j;
11417 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11418 /* Allocate num_ssid tCsrSSIDInfo structure */
11419 SsidInfo = scanRequest.SSIDs.SSIDList =
11420 ( tCsrSSIDInfo *)vos_mem_malloc(
11421 request->n_ssids*sizeof(tCsrSSIDInfo));
11422
11423 if(NULL == scanRequest.SSIDs.SSIDList)
11424 {
11425 hddLog(VOS_TRACE_LEVEL_ERROR,
11426 "%s: memory alloc failed SSIDInfo buffer", __func__);
11427 return -ENOMEM;
11428 }
11429
11430 /* copy all the ssid's and their length */
11431 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11432 {
11433 /* get the ssid length */
11434 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11435 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11436 SsidInfo->SSID.length);
11437 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11438 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11439 j, SsidInfo->SSID.ssId);
11440 }
11441 /* set the scan type to active */
11442 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11443 }
11444 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011446 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11447 TRACE_CODE_HDD_CFG80211_SCAN,
11448 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 /* set the scan type to active */
11450 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011452 else
11453 {
11454 /*Set the scan type to default type, in this case it is ACTIVE*/
11455 scanRequest.scanType = pScanInfo->scan_mode;
11456 }
11457 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11458 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011459
11460 /* set BSSType to default type */
11461 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11462
11463 /*TODO: scan the requested channels only*/
11464
11465 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011466 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011468 hddLog(VOS_TRACE_LEVEL_WARN,
11469 "No of Scan Channels exceeded limit: %d", request->n_channels);
11470 request->n_channels = MAX_CHANNEL;
11471 }
11472
11473 hddLog(VOS_TRACE_LEVEL_INFO,
11474 "No of Scan Channels: %d", request->n_channels);
11475
11476
11477 if( request->n_channels )
11478 {
11479 char chList [(request->n_channels*5)+1];
11480 int len;
11481 channelList = vos_mem_malloc( request->n_channels );
11482 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011483 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011484 hddLog(VOS_TRACE_LEVEL_ERROR,
11485 "%s: memory alloc failed channelList", __func__);
11486 status = -ENOMEM;
11487 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011488 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011489
11490 for( i = 0, len = 0; i < request->n_channels ; i++ )
11491 {
11492 channelList[i] = request->channels[i]->hw_value;
11493 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11494 }
11495
Nirav Shah20ac06f2013-12-12 18:14:06 +053011496 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011497 "Channel-List: %s ", chList);
11498 }
c_hpothu53512302014-04-15 18:49:53 +053011499
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011500 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11501 scanRequest.ChannelInfo.ChannelList = channelList;
11502
11503 /* set requestType to full scan */
11504 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11505
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011506 /* if there is back to back scan happening in driver with in
11507 * nDeferScanTimeInterval interval driver should defer new scan request
11508 * and should provide last cached scan results instead of new channel list.
11509 * This rule is not applicable if scan is p2p scan.
11510 * This condition will work only in case when last request no of channels
11511 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011512 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011513 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011514 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011515
Sushant Kaushik86592172015-04-27 16:35:03 +053011516 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11517 /* if wps ie is NULL , then only defer scan */
11518 if ( pWpsIe == NULL &&
11519 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011520 {
11521 if ( pScanInfo->last_scan_timestamp !=0 &&
11522 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11523 {
11524 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11525 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11526 vos_mem_compare(pScanInfo->last_scan_channelList,
11527 channelList, pScanInfo->last_scan_numChannels))
11528 {
11529 hddLog(VOS_TRACE_LEVEL_WARN,
11530 " New and old station scan time differ is less then %u",
11531 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11532
11533 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011534 pAdapter);
11535
Agarwal Ashish57e84372014-12-05 18:26:53 +053011536 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011537 "Return old cached scan as all channels and no of channels are same");
11538
Agarwal Ashish57e84372014-12-05 18:26:53 +053011539 if (0 > ret)
11540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011541
Agarwal Ashish57e84372014-12-05 18:26:53 +053011542 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011543
11544 status = eHAL_STATUS_SUCCESS;
11545 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011546 }
11547 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011548 }
11549
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011550 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11551 * search (Flush on both full scan and social scan but not on single
11552 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11553 */
11554
11555 /* Supplicant does single channel scan after 8-way handshake
11556 * and in that case driver shoudnt flush scan results. If
11557 * driver flushes the scan results here and unfortunately if
11558 * the AP doesnt respond to our probe req then association
11559 * fails which is not desired
11560 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011561 if ((request->n_ssids == 1)
11562 && (request->ssids != NULL)
11563 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11564 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011565
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011566 if( is_p2p_scan ||
11567 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011568 {
11569 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11570 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11571 pAdapter->sessionId );
11572 }
11573
11574 if( request->ie_len )
11575 {
11576 /* save this for future association (join requires this) */
11577 /*TODO: Array needs to be converted to dynamic allocation,
11578 * as multiple ie.s can be sent in cfg80211_scan_request structure
11579 * CR 597966
11580 */
11581 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11582 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11583 pScanInfo->scanAddIE.length = request->ie_len;
11584
11585 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11586 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11587 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011589 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011591 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11592 memcpy( pwextBuf->roamProfile.addIEScan,
11593 request->ie, request->ie_len);
11594 }
11595 else
11596 {
11597 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11598 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 }
11600
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011601 }
11602 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11603 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11604
11605 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11606 request->ie_len);
11607 if (pP2pIe != NULL)
11608 {
11609#ifdef WLAN_FEATURE_P2P_DEBUG
11610 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11611 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11612 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011613 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011614 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11615 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11616 "Go nego completed to Connection is started");
11617 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11618 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011619 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011620 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11621 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011623 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11624 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11625 "Disconnected state to Connection is started");
11626 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11627 "for 4way Handshake");
11628 }
11629#endif
11630
11631 /* no_cck will be set during p2p find to disable 11b rates */
11632 if(TRUE == request->no_cck)
11633 {
11634 hddLog(VOS_TRACE_LEVEL_INFO,
11635 "%s: This is a P2P Search", __func__);
11636 scanRequest.p2pSearch = 1;
11637
11638 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011639 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011640 /* set requestType to P2P Discovery */
11641 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11642 }
11643
11644 /*
11645 Skip Dfs Channel in case of P2P Search
11646 if it is set in ini file
11647 */
11648 if(cfg_param->skipDfsChnlInP2pSearch)
11649 {
11650 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011651 }
11652 else
11653 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011654 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011655 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011656
Agarwal Ashish4f616132013-12-30 23:32:50 +053011657 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 }
11659 }
11660
11661 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11662
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011663#ifdef FEATURE_WLAN_TDLS
11664 /* if tdls disagree scan right now, return immediately.
11665 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11666 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11667 */
11668 status = wlan_hdd_tdls_scan_callback (pAdapter,
11669 wiphy,
11670#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11671 dev,
11672#endif
11673 request);
11674 if(status <= 0)
11675 {
11676 if(!status)
11677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11678 "scan rejected %d", __func__, status);
11679 else
11680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11681 __func__, status);
11682
11683 return status;
11684 }
11685#endif
11686
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011687 /* acquire the wakelock to avoid the apps suspend during the scan. To
11688 * address the following issues.
11689 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11690 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11691 * for long time, this result in apps running at full power for long time.
11692 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11693 * be stuck in full power because of resume BMPS
11694 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011695 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011696
Nirav Shah20ac06f2013-12-12 18:14:06 +053011697 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11698 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011699 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11700 scanRequest.requestType, scanRequest.scanType,
11701 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011702 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11703
Siddharth Bhal76972212014-10-15 16:22:51 +053011704 if (pHddCtx->spoofMacAddr.isEnabled)
11705 {
11706 hddLog(VOS_TRACE_LEVEL_INFO,
11707 "%s: MAC Spoofing enabled for current scan", __func__);
11708 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11709 * to fill TxBds for probe request during current scan
11710 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011711 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011712 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011713
11714 if(status != VOS_STATUS_SUCCESS)
11715 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011716 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011717 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011718#ifdef FEATURE_WLAN_TDLS
11719 wlan_hdd_tdls_scan_done_callback(pAdapter);
11720#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011721 goto free_mem;
11722 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011723 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011724 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011725 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 pAdapter->sessionId, &scanRequest, &scanId,
11727 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 if (eHAL_STATUS_SUCCESS != status)
11730 {
11731 hddLog(VOS_TRACE_LEVEL_ERROR,
11732 "%s: sme_ScanRequest returned error %d", __func__, status);
11733 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011734 if(eHAL_STATUS_RESOURCES == status)
11735 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11737 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011738 status = -EBUSY;
11739 } else {
11740 status = -EIO;
11741 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011742 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011743
11744#ifdef FEATURE_WLAN_TDLS
11745 wlan_hdd_tdls_scan_done_callback(pAdapter);
11746#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 goto free_mem;
11748 }
11749
11750 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011751 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 pAdapter->request = request;
11753 pScanInfo->scanId = scanId;
11754
11755 complete(&pScanInfo->scan_req_completion_event);
11756
11757free_mem:
11758 if( scanRequest.SSIDs.SSIDList )
11759 {
11760 vos_mem_free(scanRequest.SSIDs.SSIDList);
11761 }
11762
11763 if( channelList )
11764 vos_mem_free( channelList );
11765
11766 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011767 return status;
11768}
11769
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011770int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11771#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11772 struct net_device *dev,
11773#endif
11774 struct cfg80211_scan_request *request)
11775{
11776 int ret;
11777
11778 vos_ssr_protect(__func__);
11779 ret = __wlan_hdd_cfg80211_scan(wiphy,
11780#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11781 dev,
11782#endif
11783 request);
11784 vos_ssr_unprotect(__func__);
11785
11786 return ret;
11787}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011788
11789void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11790{
11791 v_U8_t iniDot11Mode =
11792 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11793 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11794
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011795 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11796 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011797 switch ( iniDot11Mode )
11798 {
11799 case eHDD_DOT11_MODE_AUTO:
11800 case eHDD_DOT11_MODE_11ac:
11801 case eHDD_DOT11_MODE_11ac_ONLY:
11802#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011803 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11804 sme_IsFeatureSupportedByFW(DOT11AC) )
11805 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11806 else
11807 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011808#else
11809 hddDot11Mode = eHDD_DOT11_MODE_11n;
11810#endif
11811 break;
11812 case eHDD_DOT11_MODE_11n:
11813 case eHDD_DOT11_MODE_11n_ONLY:
11814 hddDot11Mode = eHDD_DOT11_MODE_11n;
11815 break;
11816 default:
11817 hddDot11Mode = iniDot11Mode;
11818 break;
11819 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011820#ifdef WLAN_FEATURE_AP_HT40_24G
11821 if (operationChannel > SIR_11B_CHANNEL_END)
11822#endif
11823 {
11824 /* This call decides required channel bonding mode */
11825 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011826 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11827 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011828 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011829}
11830
Jeff Johnson295189b2012-06-20 16:38:30 -070011831/*
11832 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011833 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011835int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011836 const u8 *ssid, size_t ssid_len, const u8 *bssid,
11837 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011838{
11839 int status = 0;
11840 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011841 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011842 v_U32_t roamId;
11843 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011844 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011845 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011846
11847 ENTER();
11848
11849 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011850 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11851
11852 status = wlan_hdd_validate_context(pHddCtx);
11853 if (status)
11854 {
Yue Mae36e3552014-03-05 17:06:20 -080011855 return status;
11856 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011857
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11859 {
11860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11861 return -EINVAL;
11862 }
11863
11864 pRoamProfile = &pWextState->roamProfile;
11865
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011866 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011868 hdd_station_ctx_t *pHddStaCtx;
11869 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011870
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011871 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11872
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011873 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11875 {
11876 /*QoS not enabled in cfg file*/
11877 pRoamProfile->uapsd_mask = 0;
11878 }
11879 else
11880 {
11881 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011882 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11884 }
11885
11886 pRoamProfile->SSIDs.numOfSSIDs = 1;
11887 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11888 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011889 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11891 ssid, ssid_len);
11892
11893 if (bssid)
11894 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011895 pValidBssid = bssid;
11896 }
11897 else if (bssid_hint)
11898 {
11899 pValidBssid = bssid_hint;
11900 }
11901 if (pValidBssid)
11902 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011904 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011906 /* Save BSSID in seperate variable as well, as RoamProfile
11907 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011908 case of join failure we should send valid BSSID to supplicant
11909 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011910 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 WNI_CFG_BSSID_LEN);
11912 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011913 else
11914 {
11915 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11916 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011917
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011918 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11919 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11921 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 /*set gen ie*/
11924 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11925 /*set auth*/
11926 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11927 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011928#ifdef FEATURE_WLAN_WAPI
11929 if (pAdapter->wapi_info.nWapiMode)
11930 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011931 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 switch (pAdapter->wapi_info.wapiAuthMode)
11933 {
11934 case WAPI_AUTH_MODE_PSK:
11935 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011936 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 pAdapter->wapi_info.wapiAuthMode);
11938 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11939 break;
11940 }
11941 case WAPI_AUTH_MODE_CERT:
11942 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011943 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011944 pAdapter->wapi_info.wapiAuthMode);
11945 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11946 break;
11947 }
11948 } // End of switch
11949 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11950 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11951 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011952 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 pRoamProfile->AuthType.numEntries = 1;
11954 pRoamProfile->EncryptionType.numEntries = 1;
11955 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11956 pRoamProfile->mcEncryptionType.numEntries = 1;
11957 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11958 }
11959 }
11960#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011961#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011962 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011963 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11964 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11965 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011966 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11967 sizeof (tSirGtkOffloadParams));
11968 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011969 }
11970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 pRoamProfile->csrPersona = pAdapter->device_mode;
11972
Jeff Johnson32d95a32012-09-10 13:15:23 -070011973 if( operatingChannel )
11974 {
11975 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11976 pRoamProfile->ChannelInfo.numOfChannels = 1;
11977 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011978 else
11979 {
11980 pRoamProfile->ChannelInfo.ChannelList = NULL;
11981 pRoamProfile->ChannelInfo.numOfChannels = 0;
11982 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011983 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11984 {
11985 hdd_select_cbmode(pAdapter,operatingChannel);
11986 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011987
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011988 /*
11989 * Change conn_state to connecting before sme_RoamConnect(),
11990 * because sme_RoamConnect() has a direct path to call
11991 * hdd_smeRoamCallback(), which will change the conn_state
11992 * If direct path, conn_state will be accordingly changed
11993 * to NotConnected or Associated by either
11994 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11995 * in sme_RoamCallback()
11996 * if sme_RomConnect is to be queued,
11997 * Connecting state will remain until it is completed.
11998 * If connection state is not changed,
11999 * connection state will remain in eConnectionState_NotConnected state.
12000 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12001 * if conn state is eConnectionState_NotConnected.
12002 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12003 * informed of connect result indication which is an issue.
12004 */
12005
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012006 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12007 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012008 {
12009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012010 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012011 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12012 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012013 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012014 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 pAdapter->sessionId, pRoamProfile, &roamId);
12016
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012017 if ((eHAL_STATUS_SUCCESS != status) &&
12018 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12019 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012020
12021 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012022 hddLog(VOS_TRACE_LEVEL_ERROR,
12023 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12024 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012025 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012026 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012027 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012028 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012029
12030 pRoamProfile->ChannelInfo.ChannelList = NULL;
12031 pRoamProfile->ChannelInfo.numOfChannels = 0;
12032
Jeff Johnson295189b2012-06-20 16:38:30 -070012033 }
12034 else
12035 {
12036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12037 return -EINVAL;
12038 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012039 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 return status;
12041}
12042
12043/*
12044 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12045 * This function is used to set the authentication type (OPEN/SHARED).
12046 *
12047 */
12048static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12049 enum nl80211_auth_type auth_type)
12050{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012051 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12053
12054 ENTER();
12055
12056 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012057 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012058 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012060 hddLog(VOS_TRACE_LEVEL_INFO,
12061 "%s: set authentication type to AUTOSWITCH", __func__);
12062 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12063 break;
12064
12065 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012066#ifdef WLAN_FEATURE_VOWIFI_11R
12067 case NL80211_AUTHTYPE_FT:
12068#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012069 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 "%s: set authentication type to OPEN", __func__);
12071 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12072 break;
12073
12074 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012075 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012076 "%s: set authentication type to SHARED", __func__);
12077 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12078 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012079#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012081 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 "%s: set authentication type to CCKM WPA", __func__);
12083 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12084 break;
12085#endif
12086
12087
12088 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012089 hddLog(VOS_TRACE_LEVEL_ERROR,
12090 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 auth_type);
12092 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12093 return -EINVAL;
12094 }
12095
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 pHddStaCtx->conn_info.authType;
12098 return 0;
12099}
12100
12101/*
12102 * FUNCTION: wlan_hdd_set_akm_suite
12103 * This function is used to set the key mgmt type(PSK/8021x).
12104 *
12105 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 u32 key_mgmt
12108 )
12109{
12110 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12111 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012112 /* Should be in ieee802_11_defs.h */
12113#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12114#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 /*set key mgmt type*/
12116 switch(key_mgmt)
12117 {
12118 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012119 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012120#ifdef WLAN_FEATURE_VOWIFI_11R
12121 case WLAN_AKM_SUITE_FT_PSK:
12122#endif
12123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 __func__);
12125 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12126 break;
12127
12128 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012129 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012130#ifdef WLAN_FEATURE_VOWIFI_11R
12131 case WLAN_AKM_SUITE_FT_8021X:
12132#endif
12133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 __func__);
12135 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12136 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012137#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012138#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12139#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12140 case WLAN_AKM_SUITE_CCKM:
12141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12142 __func__);
12143 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12144 break;
12145#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012146#ifndef WLAN_AKM_SUITE_OSEN
12147#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12148 case WLAN_AKM_SUITE_OSEN:
12149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12150 __func__);
12151 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12152 break;
12153#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012154
12155 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 __func__, key_mgmt);
12158 return -EINVAL;
12159
12160 }
12161 return 0;
12162}
12163
12164/*
12165 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 * (NONE/WEP40/WEP104/TKIP/CCMP).
12168 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12170 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 bool ucast
12172 )
12173{
12174 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012175 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12177
12178 ENTER();
12179
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012180 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 __func__, cipher);
12184 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12185 }
12186 else
12187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 {
12192 case IW_AUTH_CIPHER_NONE:
12193 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12194 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012197 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012201 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012203
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 case WLAN_CIPHER_SUITE_TKIP:
12205 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12206 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012207
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 case WLAN_CIPHER_SUITE_CCMP:
12209 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12210 break;
12211#ifdef FEATURE_WLAN_WAPI
12212 case WLAN_CIPHER_SUITE_SMS4:
12213 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12214 break;
12215#endif
12216
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012217#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012218 case WLAN_CIPHER_SUITE_KRK:
12219 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12220 break;
12221#endif
12222 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 __func__, cipher);
12225 return -EOPNOTSUPP;
12226 }
12227 }
12228
12229 if (ucast)
12230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012231 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 __func__, encryptionType);
12233 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12234 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012235 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 encryptionType;
12237 }
12238 else
12239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 __func__, encryptionType);
12242 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12243 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12244 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12245 }
12246
12247 return 0;
12248}
12249
12250
12251/*
12252 * FUNCTION: wlan_hdd_cfg80211_set_ie
12253 * This function is used to parse WPA/RSN IE's.
12254 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012255int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12257 const u8 *ie,
12258#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012260#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012261 size_t ie_len
12262 )
12263{
12264 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12266 const u8 *genie = ie;
12267#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012269#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 v_U16_t remLen = ie_len;
12271#ifdef FEATURE_WLAN_WAPI
12272 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12273 u16 *tmp;
12274 v_U16_t akmsuiteCount;
12275 int *akmlist;
12276#endif
12277 ENTER();
12278
12279 /* clear previous assocAddIE */
12280 pWextState->assocAddIE.length = 0;
12281 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012282 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012283
12284 while (remLen >= 2)
12285 {
12286 v_U16_t eLen = 0;
12287 v_U8_t elementId;
12288 elementId = *genie++;
12289 eLen = *genie++;
12290 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012291
Arif Hussain6d2a3322013-11-17 19:50:10 -080012292 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012294
12295 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012298 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 -070012299 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012300 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 "%s: Invalid WPA IE", __func__);
12302 return -EINVAL;
12303 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 {
12306 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012307 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012309
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012310 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012312 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12313 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 VOS_ASSERT(0);
12315 return -ENOMEM;
12316 }
12317 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12318 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12319 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12322 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12323 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12324 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012325 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12326 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12328 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12329 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12330 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12331 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12332 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012333 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012334 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 {
12336 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012337 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012339
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012340 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012341 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012342 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12343 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 VOS_ASSERT(0);
12345 return -ENOMEM;
12346 }
12347 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12348 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12349 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012350
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12352 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12353 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012354#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012355 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12356 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 /*Consider WFD IE, only for P2P Client */
12358 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12359 {
12360 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012361 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012362 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012363
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012364 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012366 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12367 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 VOS_ASSERT(0);
12369 return -ENOMEM;
12370 }
12371 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12372 // WPS IE + P2P IE + WFD IE
12373 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12374 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012375
Jeff Johnson295189b2012-06-20 16:38:30 -070012376 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12377 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12378 }
12379#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012380 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012381 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012382 HS20_OUI_TYPE_SIZE)) )
12383 {
12384 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012385 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012386 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012387
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012388 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012389 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012390 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12391 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012392 VOS_ASSERT(0);
12393 return -ENOMEM;
12394 }
12395 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12396 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012397
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012398 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12399 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12400 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012401 /* Appending OSEN Information Element in Assiciation Request */
12402 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12403 OSEN_OUI_TYPE_SIZE)) )
12404 {
12405 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12406 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12407 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012408
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012409 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012410 {
12411 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12412 "Need bigger buffer space");
12413 VOS_ASSERT(0);
12414 return -ENOMEM;
12415 }
12416 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12417 pWextState->assocAddIE.length += eLen + 2;
12418
12419 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12420 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12421 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12422 }
12423
Abhishek Singh4322e622015-06-10 15:42:54 +053012424 /* Update only for WPA IE */
12425 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12426 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012427
12428 /* populating as ADDIE in beacon frames */
12429 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012430 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012431 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12432 {
12433 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12434 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12435 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12436 {
12437 hddLog(LOGE,
12438 "Coldn't pass "
12439 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12440 }
12441 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12442 else
12443 hddLog(LOGE,
12444 "Could not pass on "
12445 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12446
12447 /* IBSS mode doesn't contain params->proberesp_ies still
12448 beaconIE's need to be populated in probe response frames */
12449 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12450 {
12451 u16 rem_probe_resp_ie_len = eLen + 2;
12452 u8 probe_rsp_ie_len[3] = {0};
12453 u8 counter = 0;
12454
12455 /* Check Probe Resp Length if it is greater then 255 then
12456 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12457 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12458 not able Store More then 255 bytes into One Variable */
12459
12460 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12461 {
12462 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12463 {
12464 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12465 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12466 }
12467 else
12468 {
12469 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12470 rem_probe_resp_ie_len = 0;
12471 }
12472 }
12473
12474 rem_probe_resp_ie_len = 0;
12475
12476 if (probe_rsp_ie_len[0] > 0)
12477 {
12478 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12479 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12480 (tANI_U8*)(genie - 2),
12481 probe_rsp_ie_len[0], NULL,
12482 eANI_BOOLEAN_FALSE)
12483 == eHAL_STATUS_FAILURE)
12484 {
12485 hddLog(LOGE,
12486 "Could not pass"
12487 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12488 }
12489 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12490 }
12491
12492 if (probe_rsp_ie_len[1] > 0)
12493 {
12494 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12495 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12496 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12497 probe_rsp_ie_len[1], NULL,
12498 eANI_BOOLEAN_FALSE)
12499 == eHAL_STATUS_FAILURE)
12500 {
12501 hddLog(LOGE,
12502 "Could not pass"
12503 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12504 }
12505 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12506 }
12507
12508 if (probe_rsp_ie_len[2] > 0)
12509 {
12510 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12511 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12512 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12513 probe_rsp_ie_len[2], NULL,
12514 eANI_BOOLEAN_FALSE)
12515 == eHAL_STATUS_FAILURE)
12516 {
12517 hddLog(LOGE,
12518 "Could not pass"
12519 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12520 }
12521 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12522 }
12523
12524 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12525 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12526 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12527 {
12528 hddLog(LOGE,
12529 "Could not pass"
12530 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12531 }
12532 }
12533 else
12534 {
12535 // Reset WNI_CFG_PROBE_RSP Flags
12536 wlan_hdd_reset_prob_rspies(pAdapter);
12537
12538 hddLog(VOS_TRACE_LEVEL_INFO,
12539 "%s: No Probe Response IE received in set beacon",
12540 __func__);
12541 }
12542 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012543 break;
12544 case DOT11F_EID_RSN:
12545 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12546 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12547 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12548 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12549 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12550 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012551
12552 /* Appending Extended Capabilities with Interworking bit set
12553 * in Assoc Req.
12554 *
12555 * In assoc req this EXT Cap will only be taken into account if
12556 * interworkingService bit is set to 1. Currently
12557 * driver is only interested in interworkingService capability
12558 * from supplicant. If in future any other EXT Cap info is
12559 * required from supplicat, it needs to be handled while
12560 * sending Assoc Req in LIM.
12561 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012562 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012563 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012564 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012565 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012566 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012567
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012568 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012569 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012570 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12571 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012572 VOS_ASSERT(0);
12573 return -ENOMEM;
12574 }
12575 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12576 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012577
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012578 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12579 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12580 break;
12581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012582#ifdef FEATURE_WLAN_WAPI
12583 case WLAN_EID_WAPI:
12584 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012585 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 pAdapter->wapi_info.nWapiMode);
12587 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012588 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012589 akmsuiteCount = WPA_GET_LE16(tmp);
12590 tmp = tmp + 1;
12591 akmlist = (int *)(tmp);
12592 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12593 {
12594 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12595 }
12596 else
12597 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012598 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012599 VOS_ASSERT(0);
12600 return -EINVAL;
12601 }
12602
12603 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12604 {
12605 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012606 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012607 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012610 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012612 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12614 }
12615 break;
12616#endif
12617 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012618 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012620 /* when Unknown IE is received we should break and continue
12621 * to the next IE in the buffer instead we were returning
12622 * so changing this to break */
12623 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 }
12625 genie += eLen;
12626 remLen -= eLen;
12627 }
12628 EXIT();
12629 return 0;
12630}
12631
12632/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012633 * FUNCTION: hdd_isWPAIEPresent
12634 * Parse the received IE to find the WPA IE
12635 *
12636 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012637static bool hdd_isWPAIEPresent(
12638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12639 const u8 *ie,
12640#else
12641 u8 *ie,
12642#endif
12643 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012644{
12645 v_U8_t eLen = 0;
12646 v_U16_t remLen = ie_len;
12647 v_U8_t elementId = 0;
12648
12649 while (remLen >= 2)
12650 {
12651 elementId = *ie++;
12652 eLen = *ie++;
12653 remLen -= 2;
12654 if (eLen > remLen)
12655 {
12656 hddLog(VOS_TRACE_LEVEL_ERROR,
12657 "%s: IE length is wrong %d", __func__, eLen);
12658 return FALSE;
12659 }
12660 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12661 {
12662 /* OUI - 0x00 0X50 0XF2
12663 WPA Information Element - 0x01
12664 WPA version - 0x01*/
12665 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12666 return TRUE;
12667 }
12668 ie += eLen;
12669 remLen -= eLen;
12670 }
12671 return FALSE;
12672}
12673
12674/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012676 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 * parameters during connect operation.
12678 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012679int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012680 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012681 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012682{
12683 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 ENTER();
12686
12687 /*set wpa version*/
12688 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12689
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012690 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012692 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 {
12694 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12695 }
12696 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12697 {
12698 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12699 }
12700 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012701
12702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 pWextState->wpaVersion);
12704
12705 /*set authentication type*/
12706 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12707
12708 if (0 > status)
12709 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012710 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 "%s: failed to set authentication type ", __func__);
12712 return status;
12713 }
12714
12715 /*set key mgmt type*/
12716 if (req->crypto.n_akm_suites)
12717 {
12718 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12719 if (0 > status)
12720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 __func__);
12723 return status;
12724 }
12725 }
12726
12727 /*set pairwise cipher type*/
12728 if (req->crypto.n_ciphers_pairwise)
12729 {
12730 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12731 req->crypto.ciphers_pairwise[0], true);
12732 if (0 > status)
12733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012734 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 "%s: failed to set unicast cipher type", __func__);
12736 return status;
12737 }
12738 }
12739 else
12740 {
12741 /*Reset previous cipher suite to none*/
12742 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12743 if (0 > status)
12744 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012745 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 "%s: failed to set unicast cipher type", __func__);
12747 return status;
12748 }
12749 }
12750
12751 /*set group cipher type*/
12752 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12753 false);
12754
12755 if (0 > status)
12756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012758 __func__);
12759 return status;
12760 }
12761
Chet Lanctot186b5732013-03-18 10:26:30 -070012762#ifdef WLAN_FEATURE_11W
12763 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12764#endif
12765
Jeff Johnson295189b2012-06-20 16:38:30 -070012766 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12767 if (req->ie_len)
12768 {
12769 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12770 if ( 0 > status)
12771 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012773 __func__);
12774 return status;
12775 }
12776 }
12777
12778 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012779 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 {
12781 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12782 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12783 )
12784 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012785 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012786 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12787 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012789 __func__);
12790 return -EOPNOTSUPP;
12791 }
12792 else
12793 {
12794 u8 key_len = req->key_len;
12795 u8 key_idx = req->key_idx;
12796
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012797 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012798 && (CSR_MAX_NUM_KEY > key_idx)
12799 )
12800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012801 hddLog(VOS_TRACE_LEVEL_INFO,
12802 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012803 __func__, key_idx, key_len);
12804 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012805 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012807 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 (u8)key_len;
12809 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12810 }
12811 }
12812 }
12813 }
12814
12815 return status;
12816}
12817
12818/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012819 * FUNCTION: wlan_hdd_try_disconnect
12820 * This function is used to disconnect from previous
12821 * connection
12822 */
12823static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12824{
12825 long ret = 0;
12826 hdd_station_ctx_t *pHddStaCtx;
12827 eMib_dot11DesiredBssType connectedBssType;
12828
12829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12830
12831 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12832
12833 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12834 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12835 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12836 {
12837 /* Issue disconnect to CSR */
12838 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12839 if( eHAL_STATUS_SUCCESS ==
12840 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12841 pAdapter->sessionId,
12842 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12843 {
12844 ret = wait_for_completion_interruptible_timeout(
12845 &pAdapter->disconnect_comp_var,
12846 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12847 if (0 >= ret)
12848 {
12849 hddLog(LOGE, FL("Failed to receive disconnect event"));
12850 return -EALREADY;
12851 }
12852 }
12853 }
12854 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12855 {
12856 ret = wait_for_completion_interruptible_timeout(
12857 &pAdapter->disconnect_comp_var,
12858 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12859 if (0 >= ret)
12860 {
12861 hddLog(LOGE, FL("Failed to receive disconnect event"));
12862 return -EALREADY;
12863 }
12864 }
12865
12866 return 0;
12867}
12868
12869/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012870 * FUNCTION: __wlan_hdd_cfg80211_connect
12871 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012872 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012873static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012874 struct net_device *ndev,
12875 struct cfg80211_connect_params *req
12876 )
12877{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012878 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012879 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012881 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012882
12883 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012884
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012885 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12886 TRACE_CODE_HDD_CFG80211_CONNECT,
12887 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012889 "%s: device_mode = %s (%d)", __func__,
12890 hdd_device_modetoString(pAdapter->device_mode),
12891 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012892
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012893 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012894 if (!pHddCtx)
12895 {
12896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12897 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012898 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012899 }
12900
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012901 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012902 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012904 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 }
12906
Agarwal Ashish51325b52014-06-16 16:50:49 +053012907 if (vos_max_concurrent_connections_reached()) {
12908 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12909 return -ECONNREFUSED;
12910 }
12911
Jeff Johnson295189b2012-06-20 16:38:30 -070012912#ifdef WLAN_BTAMP_FEATURE
12913 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012914 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012916 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012917 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012918 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012919 }
12920#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012921
12922 //If Device Mode is Station Concurrent Sessions Exit BMps
12923 //P2P Mode will be taken care in Open/close adapter
12924 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012925 (vos_concurrent_open_sessions_running())) {
12926 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12927 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012928 }
12929
12930 /*Try disconnecting if already in connected state*/
12931 status = wlan_hdd_try_disconnect(pAdapter);
12932 if ( 0 > status)
12933 {
12934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12935 " connection"));
12936 return -EALREADY;
12937 }
12938
Jeff Johnson295189b2012-06-20 16:38:30 -070012939 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012940 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012941
12942 if ( 0 > status)
12943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 __func__);
12946 return status;
12947 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012948 if ( req->channel )
12949 {
12950 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12951 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012952 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070012953 req->channel->hw_value);
12954 }
12955 else
12956 {
12957 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012958 req->ssid_len, req->bssid,
12959 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012960 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012961
Sushant Kaushikd7083982015-03-18 14:33:24 +053012962 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012963 {
12964 //ReEnable BMPS if disabled
12965 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12966 (NULL != pHddCtx))
12967 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012968 if (pHddCtx->hdd_wlan_suspended)
12969 {
12970 hdd_set_pwrparams(pHddCtx);
12971 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012972 //ReEnable Bmps and Imps back
12973 hdd_enable_bmps_imps(pHddCtx);
12974 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012976 return status;
12977 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012978 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012979 EXIT();
12980 return status;
12981}
12982
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012983static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12984 struct net_device *ndev,
12985 struct cfg80211_connect_params *req)
12986{
12987 int ret;
12988 vos_ssr_protect(__func__);
12989 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12990 vos_ssr_unprotect(__func__);
12991
12992 return ret;
12993}
Jeff Johnson295189b2012-06-20 16:38:30 -070012994
12995/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012996 * FUNCTION: wlan_hdd_disconnect
12997 * This function is used to issue a disconnect request to SME
12998 */
12999int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13000{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013001 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013002 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013003 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013004 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013006 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013007
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013008 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013009 if (0 != status)
13010 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013011 return status;
13012 }
13013
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013014 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13015 {
13016 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13017 pAdapter->sessionId);
13018 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013019 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013020
Agarwal Ashish47d18112014-08-04 19:55:07 +053013021 /* Need to apply spin lock before decreasing active sessions
13022 * as there can be chance for double decrement if context switch
13023 * Calls hdd_DisConnectHandler.
13024 */
13025
13026 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013027 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13028 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013029 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13030 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013031 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13032 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013033
Abhishek Singhf4669da2014-05-26 15:07:49 +053013034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013035 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13036
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013037 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013038
Mihir Shete182a0b22014-08-18 16:08:48 +053013039 /*
13040 * stop tx queues before deleting STA/BSS context from the firmware.
13041 * tx has to be disabled because the firmware can get busy dropping
13042 * the tx frames after BSS/STA has been deleted and will not send
13043 * back a response resulting in WDI timeout
13044 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013046 netif_tx_disable(pAdapter->dev);
13047 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013048
Mihir Shete182a0b22014-08-18 16:08:48 +053013049 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013050 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13051 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013052 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13053 {
13054 hddLog(VOS_TRACE_LEVEL_INFO,
13055 FL("status = %d, already disconnected"),
13056 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013057
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013058 }
13059 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013060 {
13061 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013062 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013063 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013064 result = -EINVAL;
13065 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013066 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013067 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013068 &pAdapter->disconnect_comp_var,
13069 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013070 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013071 {
13072 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013073 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013074 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013075 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013076 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013077 {
13078 hddLog(VOS_TRACE_LEVEL_ERROR,
13079 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013080 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013081 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013082disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13084 FL("Set HDD connState to eConnectionState_NotConnected"));
13085 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13086
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013087 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013088 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013089}
13090
13091
13092/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013093 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 * This function is used to issue a disconnect request to SME
13095 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013096static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 struct net_device *dev,
13098 u16 reason
13099 )
13100{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013102 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013103 tCsrRoamProfile *pRoamProfile;
13104 hdd_station_ctx_t *pHddStaCtx;
13105 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013106#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013107 tANI_U8 staIdx;
13108#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013109
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013111
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013112 if (!pAdapter) {
13113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13114 return -EINVAL;
13115 }
13116
13117 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13118 if (!pHddStaCtx) {
13119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13120 return -EINVAL;
13121 }
13122
13123 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13124 status = wlan_hdd_validate_context(pHddCtx);
13125 if (0 != status)
13126 {
13127 return status;
13128 }
13129
13130 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13131
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13133 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13134 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013135 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13136 __func__, hdd_device_modetoString(pAdapter->device_mode),
13137 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013138
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13140 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013141
Jeff Johnson295189b2012-06-20 16:38:30 -070013142 if (NULL != pRoamProfile)
13143 {
13144 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013145 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13146 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013147 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013148 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013150 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013151 switch(reason)
13152 {
13153 case WLAN_REASON_MIC_FAILURE:
13154 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13155 break;
13156
13157 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13158 case WLAN_REASON_DISASSOC_AP_BUSY:
13159 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13160 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13161 break;
13162
13163 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13164 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013165 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13167 break;
13168
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 default:
13170 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13171 break;
13172 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013173 pScanInfo = &pHddCtx->scan_info;
13174 if (pScanInfo->mScanPending)
13175 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013176 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013177 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013178 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013179 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013180 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013181 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013182#ifdef FEATURE_WLAN_TDLS
13183 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013184 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013185 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013186 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13187 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013188 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013189 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013190 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013192 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013193 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013194 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013195 status = sme_DeleteTdlsPeerSta(
13196 WLAN_HDD_GET_HAL_CTX(pAdapter),
13197 pAdapter->sessionId,
13198 mac);
13199 if (status != eHAL_STATUS_SUCCESS) {
13200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13201 return -EPERM;
13202 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013203 }
13204 }
13205#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013206 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013207 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13208 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013209 {
13210 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013211 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013212 __func__, (int)status );
13213 return -EINVAL;
13214 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013215 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013216 else
13217 {
13218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13219 "called while in %d state", __func__,
13220 pHddStaCtx->conn_info.connState);
13221 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 }
13223 else
13224 {
13225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13226 }
13227
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013228 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 return status;
13230}
13231
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013232static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13233 struct net_device *dev,
13234 u16 reason
13235 )
13236{
13237 int ret;
13238 vos_ssr_protect(__func__);
13239 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13240 vos_ssr_unprotect(__func__);
13241
13242 return ret;
13243}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013244
Jeff Johnson295189b2012-06-20 16:38:30 -070013245/*
13246 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 * settings in IBSS mode.
13249 */
13250static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013251 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 struct cfg80211_ibss_params *params
13253 )
13254{
13255 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013256 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013257 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13258 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013259
Jeff Johnson295189b2012-06-20 16:38:30 -070013260 ENTER();
13261
13262 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013263 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013264
13265 if (params->ie_len && ( NULL != params->ie) )
13266 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013267 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13268 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 {
13270 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13271 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13272 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013273 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013275 tDot11fIEWPA dot11WPAIE;
13276 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013277 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013278
Wilson Yang00256342013-10-10 23:13:38 -070013279 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013280 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13281 params->ie_len, DOT11F_EID_WPA);
13282 if ( NULL != ie )
13283 {
13284 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13285 // Unpack the WPA IE
13286 //Skip past the EID byte and length byte - and four byte WiFi OUI
13287 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13288 &ie[2+4],
13289 ie[1] - 4,
13290 &dot11WPAIE);
13291 /*Extract the multicast cipher, the encType for unicast
13292 cipher for wpa-none is none*/
13293 encryptionType =
13294 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13295 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013296 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013297
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13299
13300 if (0 > status)
13301 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 __func__);
13304 return status;
13305 }
13306 }
13307
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013308 pWextState->roamProfile.AuthType.authType[0] =
13309 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13311
13312 if (params->privacy)
13313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013314 /* Security enabled IBSS, At this time there is no information available
13315 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013317 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013318 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013319 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 *enable privacy bit in beacons */
13321
13322 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13323 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013324 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13325 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13327 pWextState->roamProfile.EncryptionType.numEntries = 1;
13328 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 return status;
13330}
13331
13332/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013333 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013334 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013335 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013336static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 struct net_device *dev,
13338 struct cfg80211_ibss_params *params
13339 )
13340{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013341 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013342 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13343 tCsrRoamProfile *pRoamProfile;
13344 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013345 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13346 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013347 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013348
13349 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013350
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13352 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13353 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013354 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013355 "%s: device_mode = %s (%d)", __func__,
13356 hdd_device_modetoString(pAdapter->device_mode),
13357 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013358
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013359 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013360 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013361 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013362 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 }
13364
13365 if (NULL == pWextState)
13366 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013367 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 __func__);
13369 return -EIO;
13370 }
13371
Agarwal Ashish51325b52014-06-16 16:50:49 +053013372 if (vos_max_concurrent_connections_reached()) {
13373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13374 return -ECONNREFUSED;
13375 }
13376
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013377 /*Try disconnecting if already in connected state*/
13378 status = wlan_hdd_try_disconnect(pAdapter);
13379 if ( 0 > status)
13380 {
13381 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13382 " IBSS connection"));
13383 return -EALREADY;
13384 }
13385
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 pRoamProfile = &pWextState->roamProfile;
13387
13388 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013390 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013391 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 return -EINVAL;
13393 }
13394
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013395 /* BSSID is provided by upper layers hence no need to AUTO generate */
13396 if (NULL != params->bssid) {
13397 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13398 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13399 hddLog (VOS_TRACE_LEVEL_ERROR,
13400 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13401 return -EIO;
13402 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013403 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013404 }
krunal sonie9002db2013-11-25 14:24:17 -080013405 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13406 {
13407 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13408 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13409 {
13410 hddLog (VOS_TRACE_LEVEL_ERROR,
13411 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13412 return -EIO;
13413 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013414
13415 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013416 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013417 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013418 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013419
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013421 if (NULL !=
13422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13423 params->chandef.chan)
13424#else
13425 params->channel)
13426#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 {
13428 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013429 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13430 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13431 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13432 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013433
13434 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013435 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013436 ieee80211_frequency_to_channel(
13437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13438 params->chandef.chan->center_freq);
13439#else
13440 params->channel->center_freq);
13441#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013442
13443 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13444 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13447 __func__);
13448 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013450
13451 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013453 if (channelNum == validChan[indx])
13454 {
13455 break;
13456 }
13457 }
13458 if (indx >= numChans)
13459 {
13460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 __func__, channelNum);
13462 return -EINVAL;
13463 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013464 /* Set the Operational Channel */
13465 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13466 channelNum);
13467 pRoamProfile->ChannelInfo.numOfChannels = 1;
13468 pHddStaCtx->conn_info.operationChannel = channelNum;
13469 pRoamProfile->ChannelInfo.ChannelList =
13470 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 }
13472
13473 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013474 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 if (status < 0)
13476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 __func__);
13479 return status;
13480 }
13481
13482 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013483 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013484 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013485 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013486
13487 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013490 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013491 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013492}
13493
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013494static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13495 struct net_device *dev,
13496 struct cfg80211_ibss_params *params
13497 )
13498{
13499 int ret = 0;
13500
13501 vos_ssr_protect(__func__);
13502 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13503 vos_ssr_unprotect(__func__);
13504
13505 return ret;
13506}
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013509 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013510 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013511 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013512static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 struct net_device *dev
13514 )
13515{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013517 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13518 tCsrRoamProfile *pRoamProfile;
13519 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013520 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013521
13522 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13525 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13526 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013527 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013528 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013529 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013530 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013531 }
13532
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13534 hdd_device_modetoString(pAdapter->device_mode),
13535 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013536 if (NULL == pWextState)
13537 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013538 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 __func__);
13540 return -EIO;
13541 }
13542
13543 pRoamProfile = &pWextState->roamProfile;
13544
13545 /* Issue disconnect only if interface type is set to IBSS */
13546 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013548 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 __func__);
13550 return -EINVAL;
13551 }
13552
13553 /* Issue Disconnect request */
13554 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13555 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13556 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13557
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013558 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 return 0;
13560}
13561
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013562static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13563 struct net_device *dev
13564 )
13565{
13566 int ret = 0;
13567
13568 vos_ssr_protect(__func__);
13569 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13570 vos_ssr_unprotect(__func__);
13571
13572 return ret;
13573}
13574
Jeff Johnson295189b2012-06-20 16:38:30 -070013575/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013576 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 * This function is used to set the phy parameters
13578 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13579 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013580static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 u32 changed)
13582{
13583 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13584 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013585 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013586
13587 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013588
13589 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013590 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13591 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013592
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013593 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013594 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013595 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013596 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013597 }
13598
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13600 {
13601 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13602 WNI_CFG_RTS_THRESHOLD_STAMAX :
13603 wiphy->rts_threshold;
13604
13605 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013608 hddLog(VOS_TRACE_LEVEL_ERROR,
13609 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 __func__, rts_threshold);
13611 return -EINVAL;
13612 }
13613
13614 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13615 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013616 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013618 hddLog(VOS_TRACE_LEVEL_ERROR,
13619 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 __func__, rts_threshold);
13621 return -EIO;
13622 }
13623
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013624 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 rts_threshold);
13626 }
13627
13628 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13629 {
13630 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13631 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13632 wiphy->frag_threshold;
13633
13634 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013637 hddLog(VOS_TRACE_LEVEL_ERROR,
13638 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 frag_threshold);
13640 return -EINVAL;
13641 }
13642
13643 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13644 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013647 hddLog(VOS_TRACE_LEVEL_ERROR,
13648 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 __func__, frag_threshold);
13650 return -EIO;
13651 }
13652
13653 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13654 frag_threshold);
13655 }
13656
13657 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13658 || (changed & WIPHY_PARAM_RETRY_LONG))
13659 {
13660 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13661 wiphy->retry_short :
13662 wiphy->retry_long;
13663
13664 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13665 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13666 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 __func__, retry_value);
13669 return -EINVAL;
13670 }
13671
13672 if (changed & WIPHY_PARAM_RETRY_SHORT)
13673 {
13674 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13675 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013676 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013678 hddLog(VOS_TRACE_LEVEL_ERROR,
13679 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 __func__, retry_value);
13681 return -EIO;
13682 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 __func__, retry_value);
13685 }
13686 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13687 {
13688 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13689 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013690 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013692 hddLog(VOS_TRACE_LEVEL_ERROR,
13693 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 __func__, retry_value);
13695 return -EIO;
13696 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013697 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 __func__, retry_value);
13699 }
13700 }
13701
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013702 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 return 0;
13704}
13705
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013706static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13707 u32 changed)
13708{
13709 int ret;
13710
13711 vos_ssr_protect(__func__);
13712 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13713 vos_ssr_unprotect(__func__);
13714
13715 return ret;
13716}
13717
Jeff Johnson295189b2012-06-20 16:38:30 -070013718/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013719 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 * This function is used to set the txpower
13721 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013722static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013723#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13724 struct wireless_dev *wdev,
13725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013726#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013728#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013729 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013730#endif
13731 int dbm)
13732{
13733 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013734 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13736 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013737 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013738
13739 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013740
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13742 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13743 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013744 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013745 if (0 != status)
13746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013747 return status;
13748 }
13749
13750 hHal = pHddCtx->hHal;
13751
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013752 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13753 dbm, ccmCfgSetCallback,
13754 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013756 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13758 return -EIO;
13759 }
13760
13761 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13762 dbm);
13763
13764 switch(type)
13765 {
13766 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13767 /* Fall through */
13768 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13769 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13772 __func__);
13773 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 }
13775 break;
13776 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 __func__);
13779 return -EOPNOTSUPP;
13780 break;
13781 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13783 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 return -EIO;
13785 }
13786
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013787 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 return 0;
13789}
13790
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013791static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13792#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13793 struct wireless_dev *wdev,
13794#endif
13795#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13796 enum tx_power_setting type,
13797#else
13798 enum nl80211_tx_power_setting type,
13799#endif
13800 int dbm)
13801{
13802 int ret;
13803 vos_ssr_protect(__func__);
13804 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13805#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13806 wdev,
13807#endif
13808#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13809 type,
13810#else
13811 type,
13812#endif
13813 dbm);
13814 vos_ssr_unprotect(__func__);
13815
13816 return ret;
13817}
13818
Jeff Johnson295189b2012-06-20 16:38:30 -070013819/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013820 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 * This function is used to read the txpower
13822 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013823static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013824#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13825 struct wireless_dev *wdev,
13826#endif
13827 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013828{
13829
13830 hdd_adapter_t *pAdapter;
13831 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013832 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013833
Jeff Johnsone7245742012-09-05 17:12:55 -070013834 ENTER();
13835
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013836 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013837 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013838 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013839 *dbm = 0;
13840 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013841 }
13842
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13844 if (NULL == pAdapter)
13845 {
13846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13847 return -ENOENT;
13848 }
13849
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013850 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13851 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13852 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 wlan_hdd_get_classAstats(pAdapter);
13854 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13855
Jeff Johnsone7245742012-09-05 17:12:55 -070013856 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 return 0;
13858}
13859
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013860static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13861#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13862 struct wireless_dev *wdev,
13863#endif
13864 int *dbm)
13865{
13866 int ret;
13867
13868 vos_ssr_protect(__func__);
13869 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13870#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13871 wdev,
13872#endif
13873 dbm);
13874 vos_ssr_unprotect(__func__);
13875
13876 return ret;
13877}
13878
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013879static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13881 const u8* mac,
13882#else
13883 u8* mac,
13884#endif
13885 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013886{
13887 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13888 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13889 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013890 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013891
13892 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13893 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013894
13895 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13896 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13897 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13898 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13899 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13900 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13901 tANI_U16 maxRate = 0;
13902 tANI_U16 myRate;
13903 tANI_U16 currentRate = 0;
13904 tANI_U8 maxSpeedMCS = 0;
13905 tANI_U8 maxMCSIdx = 0;
13906 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013907 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013908 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013909 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013910
Leo Chang6f8870f2013-03-26 18:11:36 -070013911#ifdef WLAN_FEATURE_11AC
13912 tANI_U32 vht_mcs_map;
13913 eDataRate11ACMaxMcs vhtMaxMcs;
13914#endif /* WLAN_FEATURE_11AC */
13915
Jeff Johnsone7245742012-09-05 17:12:55 -070013916 ENTER();
13917
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13919 (0 == ssidlen))
13920 {
13921 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13922 " Invalid ssidlen, %d", __func__, ssidlen);
13923 /*To keep GUI happy*/
13924 return 0;
13925 }
13926
Mukul Sharma811205f2014-07-09 21:07:30 +053013927 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13928 {
13929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13930 "%s: Roaming in progress, so unable to proceed this request", __func__);
13931 return 0;
13932 }
13933
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013934 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013935 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013936 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013937 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013938 }
13939
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013940 wlan_hdd_get_station_stats(pAdapter);
13941 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013942
Kiet Lam3b17fc82013-09-27 05:24:08 +053013943 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13944 sinfo->filled |= STATION_INFO_SIGNAL;
13945
c_hpothu09f19542014-05-30 21:53:31 +053013946 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013947 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13948 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013949 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013950 {
13951 rate_flags = pAdapter->maxRateFlags;
13952 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013953
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 //convert to the UI units of 100kbps
13955 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13956
13957#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013958 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 -070013959 sinfo->signal,
13960 pCfg->reportMaxLinkSpeed,
13961 myRate,
13962 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013963 (int) pCfg->linkSpeedRssiMid,
13964 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013965 (int) rate_flags,
13966 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013967#endif //LINKSPEED_DEBUG_ENABLED
13968
13969 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13970 {
13971 // we do not want to necessarily report the current speed
13972 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13973 {
13974 // report the max possible speed
13975 rssidx = 0;
13976 }
13977 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13978 {
13979 // report the max possible speed with RSSI scaling
13980 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13981 {
13982 // report the max possible speed
13983 rssidx = 0;
13984 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013985 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 {
13987 // report middle speed
13988 rssidx = 1;
13989 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013990 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13991 {
13992 // report middle speed
13993 rssidx = 2;
13994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 else
13996 {
13997 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013998 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 }
14000 }
14001 else
14002 {
14003 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14004 hddLog(VOS_TRACE_LEVEL_ERROR,
14005 "%s: Invalid value for reportMaxLinkSpeed: %u",
14006 __func__, pCfg->reportMaxLinkSpeed);
14007 rssidx = 0;
14008 }
14009
14010 maxRate = 0;
14011
14012 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014013 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14014 OperationalRates, &ORLeng))
14015 {
14016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14017 /*To keep GUI happy*/
14018 return 0;
14019 }
14020
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 for (i = 0; i < ORLeng; i++)
14022 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014023 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014024 {
14025 /* Validate Rate Set */
14026 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14027 {
14028 currentRate = supported_data_rate[j].supported_rate[rssidx];
14029 break;
14030 }
14031 }
14032 /* Update MAX rate */
14033 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14034 }
14035
14036 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014037 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14038 ExtendedRates, &ERLeng))
14039 {
14040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14041 /*To keep GUI happy*/
14042 return 0;
14043 }
14044
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 for (i = 0; i < ERLeng; i++)
14046 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014047 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 {
14049 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14050 {
14051 currentRate = supported_data_rate[j].supported_rate[rssidx];
14052 break;
14053 }
14054 }
14055 /* Update MAX rate */
14056 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14057 }
c_hpothu79aab322014-07-14 21:11:01 +053014058
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014059 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014060 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014061 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014062 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 {
c_hpothu79aab322014-07-14 21:11:01 +053014064 if (rate_flags & eHAL_TX_RATE_VHT80)
14065 mode = 2;
14066 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14067 mode = 1;
14068 else
14069 mode = 0;
14070
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014071 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14072 MCSRates, &MCSLeng))
14073 {
14074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14075 /*To keep GUI happy*/
14076 return 0;
14077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014078 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014079#ifdef WLAN_FEATURE_11AC
14080 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014081 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014083 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014084 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014085 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014087 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014089 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014091 maxMCSIdx = 7;
14092 }
14093 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14094 {
14095 maxMCSIdx = 8;
14096 }
14097 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14098 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014099 //VHT20 is supporting 0~8
14100 if (rate_flags & eHAL_TX_RATE_VHT20)
14101 maxMCSIdx = 8;
14102 else
14103 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014104 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014105
c_hpothu79aab322014-07-14 21:11:01 +053014106 if (0 != rssidx)/*check for scaled */
14107 {
14108 //get middle rate MCS index if rssi=1/2
14109 for (i=0; i <= maxMCSIdx; i++)
14110 {
14111 if (sinfo->signal <= rssiMcsTbl[mode][i])
14112 {
14113 maxMCSIdx = i;
14114 break;
14115 }
14116 }
14117 }
14118
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014119 if (rate_flags & eHAL_TX_RATE_VHT80)
14120 {
14121 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14122 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14123 }
14124 else if (rate_flags & eHAL_TX_RATE_VHT40)
14125 {
14126 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14127 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14128 }
14129 else if (rate_flags & eHAL_TX_RATE_VHT20)
14130 {
14131 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14132 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14133 }
14134
Leo Chang6f8870f2013-03-26 18:11:36 -070014135 maxSpeedMCS = 1;
14136 if (currentRate > maxRate)
14137 {
14138 maxRate = currentRate;
14139 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014140
Leo Chang6f8870f2013-03-26 18:11:36 -070014141 }
14142 else
14143#endif /* WLAN_FEATURE_11AC */
14144 {
14145 if (rate_flags & eHAL_TX_RATE_HT40)
14146 {
14147 rateFlag |= 1;
14148 }
14149 if (rate_flags & eHAL_TX_RATE_SGI)
14150 {
14151 rateFlag |= 2;
14152 }
14153
Girish Gowli01abcee2014-07-31 20:18:55 +053014154 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014155 if (rssidx == 1 || rssidx == 2)
14156 {
14157 //get middle rate MCS index if rssi=1/2
14158 for (i=0; i <= 7; i++)
14159 {
14160 if (sinfo->signal <= rssiMcsTbl[mode][i])
14161 {
14162 temp = i+1;
14163 break;
14164 }
14165 }
14166 }
c_hpothu79aab322014-07-14 21:11:01 +053014167
14168 for (i = 0; i < MCSLeng; i++)
14169 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014170 for (j = 0; j < temp; j++)
14171 {
14172 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14173 {
14174 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014175 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014176 break;
14177 }
14178 }
14179 if ((j < temp) && (currentRate > maxRate))
14180 {
14181 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014184 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 }
14186 }
14187
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014188 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14189 {
14190 maxRate = myRate;
14191 maxSpeedMCS = 1;
14192 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14193 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014195 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014196 {
14197 maxRate = myRate;
14198 if (rate_flags & eHAL_TX_RATE_LEGACY)
14199 {
14200 maxSpeedMCS = 0;
14201 }
14202 else
14203 {
14204 maxSpeedMCS = 1;
14205 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14206 }
14207 }
14208
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014209 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 {
14211 sinfo->txrate.legacy = maxRate;
14212#ifdef LINKSPEED_DEBUG_ENABLED
14213 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14214#endif //LINKSPEED_DEBUG_ENABLED
14215 }
14216 else
14217 {
14218 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014219#ifdef WLAN_FEATURE_11AC
14220 sinfo->txrate.nss = 1;
14221 if (rate_flags & eHAL_TX_RATE_VHT80)
14222 {
14223 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014224 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014225 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014226 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014227 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014228 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14229 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14230 }
14231 else if (rate_flags & eHAL_TX_RATE_VHT20)
14232 {
14233 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14234 }
14235#endif /* WLAN_FEATURE_11AC */
14236 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14237 {
14238 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14239 if (rate_flags & eHAL_TX_RATE_HT40)
14240 {
14241 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14242 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014243 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 if (rate_flags & eHAL_TX_RATE_SGI)
14245 {
14246 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14247 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014248
Jeff Johnson295189b2012-06-20 16:38:30 -070014249#ifdef LINKSPEED_DEBUG_ENABLED
14250 pr_info("Reporting MCS rate %d flags %x\n",
14251 sinfo->txrate.mcs,
14252 sinfo->txrate.flags );
14253#endif //LINKSPEED_DEBUG_ENABLED
14254 }
14255 }
14256 else
14257 {
14258 // report current rate instead of max rate
14259
14260 if (rate_flags & eHAL_TX_RATE_LEGACY)
14261 {
14262 //provide to the UI in units of 100kbps
14263 sinfo->txrate.legacy = myRate;
14264#ifdef LINKSPEED_DEBUG_ENABLED
14265 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14266#endif //LINKSPEED_DEBUG_ENABLED
14267 }
14268 else
14269 {
14270 //must be MCS
14271 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014272#ifdef WLAN_FEATURE_11AC
14273 sinfo->txrate.nss = 1;
14274 if (rate_flags & eHAL_TX_RATE_VHT80)
14275 {
14276 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14277 }
14278 else
14279#endif /* WLAN_FEATURE_11AC */
14280 {
14281 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14282 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 if (rate_flags & eHAL_TX_RATE_SGI)
14284 {
14285 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14286 }
14287 if (rate_flags & eHAL_TX_RATE_HT40)
14288 {
14289 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14290 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014291#ifdef WLAN_FEATURE_11AC
14292 else if (rate_flags & eHAL_TX_RATE_VHT80)
14293 {
14294 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14295 }
14296#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014297#ifdef LINKSPEED_DEBUG_ENABLED
14298 pr_info("Reporting actual MCS rate %d flags %x\n",
14299 sinfo->txrate.mcs,
14300 sinfo->txrate.flags );
14301#endif //LINKSPEED_DEBUG_ENABLED
14302 }
14303 }
14304 sinfo->filled |= STATION_INFO_TX_BITRATE;
14305
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014306 sinfo->tx_packets =
14307 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14308 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14309 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14310 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14311
14312 sinfo->tx_retries =
14313 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14314 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14315 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14316 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14317
14318 sinfo->tx_failed =
14319 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14320 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14321 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14322 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14323
14324 sinfo->filled |=
14325 STATION_INFO_TX_PACKETS |
14326 STATION_INFO_TX_RETRIES |
14327 STATION_INFO_TX_FAILED;
14328
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14330 TRACE_CODE_HDD_CFG80211_GET_STA,
14331 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014332 EXIT();
14333 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014334}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14336static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14337 const u8* mac, struct station_info *sinfo)
14338#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014339static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14340 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014341#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014342{
14343 int ret;
14344
14345 vos_ssr_protect(__func__);
14346 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14347 vos_ssr_unprotect(__func__);
14348
14349 return ret;
14350}
14351
14352static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014353 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014354{
14355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014356 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014358 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014359
Jeff Johnsone7245742012-09-05 17:12:55 -070014360 ENTER();
14361
Jeff Johnson295189b2012-06-20 16:38:30 -070014362 if (NULL == pAdapter)
14363 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 return -ENODEV;
14366 }
14367
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14369 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14370 pAdapter->sessionId, timeout));
14371
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014372 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014374 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014376 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014377 }
14378
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014379 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14380 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14381 (pHddCtx->cfg_ini->fhostArpOffload) &&
14382 (eConnectionState_Associated ==
14383 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14384 {
Amar Singhald53568e2013-09-26 11:03:45 -070014385
14386 hddLog(VOS_TRACE_LEVEL_INFO,
14387 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014388 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014389 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14390 {
14391 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014392 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014393 __func__, vos_status);
14394 }
14395 }
14396
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 /**The get power cmd from the supplicant gets updated by the nl only
14398 *on successful execution of the function call
14399 *we are oppositely mapped w.r.t mode in the driver
14400 **/
14401 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14402
14403 if (VOS_STATUS_E_FAILURE == vos_status)
14404 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14406 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014407 return -EINVAL;
14408 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014409 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 return 0;
14411}
14412
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014413static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14414 struct net_device *dev, bool mode, int timeout)
14415{
14416 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014417
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014418 vos_ssr_protect(__func__);
14419 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14420 vos_ssr_unprotect(__func__);
14421
14422 return ret;
14423}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014424static const struct
14425nla_policy
14426qca_wlan_vendor_get_wifi_info_policy[
14427 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
14428 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
14429 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
14430};
14431
14432/**
14433 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
14434 * @wiphy: pointer to wireless wiphy structure.
14435 * @wdev: pointer to wireless_dev structure.
14436 * @data: Pointer to the data to be passed via vendor interface
14437 * @data_len:Length of the data to be passed
14438 *
14439 * This is called when wlan driver needs to send wifi driver related info
14440 * (driver/fw version) to the user space application upon request.
14441 *
14442 * Return: Return the Success or Failure code.
14443 */
14444static int
14445wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
14446 struct wireless_dev *wdev,
14447 const void *data, int data_len)
14448{
14449 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
14450 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
14451 tSirVersionString version;
14452 uint32 version_len;
14453 uint8 attr;
14454 int status;
14455 struct sk_buff *reply_skb = NULL;
14456
14457 if (VOS_FTM_MODE == hdd_get_conparam()) {
14458 hddLog(LOGE, FL("Command not allowed in FTM mode"));
14459 return -EINVAL;
14460 }
14461
14462 status = wlan_hdd_validate_context(hdd_ctx);
14463 if (0 != status) {
14464 hddLog(LOGE, FL("HDD context is not valid"));
14465 return -EINVAL;
14466 }
14467
14468 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
14469 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
14470 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
14471 return -EINVAL;
14472 }
14473
14474 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
14475 hddLog(LOG1, FL("Rcvd req for Driver version "
14476 "Driver version is %s"),QWLAN_VERSIONSTR);
14477 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
14478 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
14479 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
14480 hddLog(LOG1, FL("Rcvd req for FW version "
14481 "FW version is %s"), hdd_ctx->fw_Version);
14482 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
14483 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
14484 } else {
14485 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
14486 return -EINVAL;
14487 }
14488
14489 version_len = strlen(version);
14490 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
14491 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
14492 if (!reply_skb) {
14493 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
14494 return -ENOMEM;
14495 }
14496
14497 if (nla_put(reply_skb, attr, version_len, version)) {
14498 hddLog(LOGE, FL("nla put fail"));
14499 kfree_skb(reply_skb);
14500 return -EINVAL;
14501 }
14502
14503 return cfg80211_vendor_cmd_reply(reply_skb);
14504}
14505
Jeff Johnson295189b2012-06-20 16:38:30 -070014506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014507static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14508 struct net_device *netdev,
14509 u8 key_index)
14510{
14511 ENTER();
14512 return 0;
14513}
14514
Jeff Johnson295189b2012-06-20 16:38:30 -070014515static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014516 struct net_device *netdev,
14517 u8 key_index)
14518{
14519 int ret;
14520 vos_ssr_protect(__func__);
14521 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14522 vos_ssr_unprotect(__func__);
14523 return ret;
14524}
14525#endif //LINUX_VERSION_CODE
14526
14527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14528static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14529 struct net_device *dev,
14530 struct ieee80211_txq_params *params)
14531{
14532 ENTER();
14533 return 0;
14534}
14535#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14536static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14537 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014538{
Jeff Johnsone7245742012-09-05 17:12:55 -070014539 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 return 0;
14541}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014543
14544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14545static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014546 struct net_device *dev,
14547 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014548{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014549 int ret;
14550
14551 vos_ssr_protect(__func__);
14552 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14553 vos_ssr_unprotect(__func__);
14554 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014555}
14556#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14557static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14558 struct ieee80211_txq_params *params)
14559{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014560 int ret;
14561
14562 vos_ssr_protect(__func__);
14563 ret = __wlan_hdd_set_txq_params(wiphy, params);
14564 vos_ssr_unprotect(__func__);
14565 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014566}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014567#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014568
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014569static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014570 struct net_device *dev,
14571 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014572{
14573 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014574 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014575 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014576 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014577 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014578 v_CONTEXT_t pVosContext = NULL;
14579 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014580
Jeff Johnsone7245742012-09-05 17:12:55 -070014581 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014582
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014583 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014584 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 return -EINVAL;
14587 }
14588
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014589 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14590 TRACE_CODE_HDD_CFG80211_DEL_STA,
14591 pAdapter->sessionId, pAdapter->device_mode));
14592
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014593 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14594 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014595 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014596 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014597 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014598 }
14599
Jeff Johnson295189b2012-06-20 16:38:30 -070014600 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014601 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014602 )
14603 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014604 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14605 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14606 if(pSapCtx == NULL){
14607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14608 FL("psapCtx is NULL"));
14609 return -ENOENT;
14610 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014611 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014612 {
14613 v_U16_t i;
14614 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14615 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014616 if ((pSapCtx->aStaInfo[i].isUsed) &&
14617 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014618 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014619 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014620 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014621 ETHER_ADDR_LEN);
14622
Jeff Johnson295189b2012-06-20 16:38:30 -070014623 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014624 "%s: Delete STA with MAC::"
14625 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014626 __func__,
14627 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14628 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014629 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014630 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 }
14632 }
14633 }
14634 else
14635 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014636
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014637 vos_status = hdd_softap_GetStaId(pAdapter,
14638 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014639 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14640 {
14641 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014642 "%s: Skip this DEL STA as this is not used::"
14643 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014644 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014645 return -ENOENT;
14646 }
14647
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014648 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014649 {
14650 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014651 "%s: Skip this DEL STA as deauth is in progress::"
14652 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014653 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014654 return -ENOENT;
14655 }
14656
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014657 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014658
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 hddLog(VOS_TRACE_LEVEL_INFO,
14660 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014661 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014662 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014663 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014664
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014665 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014666 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14667 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014668 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014669 hddLog(VOS_TRACE_LEVEL_INFO,
14670 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014671 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014672 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014673 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014674 return -ENOENT;
14675 }
14676
Jeff Johnson295189b2012-06-20 16:38:30 -070014677 }
14678 }
14679
14680 EXIT();
14681
14682 return 0;
14683}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014684
14685#ifdef CFG80211_DEL_STA_V2
14686static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14687 struct net_device *dev,
14688 struct station_del_parameters *param)
14689#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014690#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14691static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14692 struct net_device *dev, const u8 *mac)
14693#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014694static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14695 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014696#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014697#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014698{
14699 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014700 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014701
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014702 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014703
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014704#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014705 if (NULL == param) {
14706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014707 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014708 return -EINVAL;
14709 }
14710
14711 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14712 param->subtype, &delStaParams);
14713
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014714#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014715 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014716 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014717#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014718 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14719
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014720 vos_ssr_unprotect(__func__);
14721
14722 return ret;
14723}
14724
14725static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014726 struct net_device *dev,
14727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14728 const u8 *mac,
14729#else
14730 u8 *mac,
14731#endif
14732 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014733{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014734 hdd_adapter_t *pAdapter;
14735 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014736 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014737#ifdef FEATURE_WLAN_TDLS
14738 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014739
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014740 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014741
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014742 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14743 if (NULL == pAdapter)
14744 {
14745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14746 "%s: Adapter is NULL",__func__);
14747 return -EINVAL;
14748 }
14749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14750 status = wlan_hdd_validate_context(pHddCtx);
14751 if (0 != status)
14752 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014753 return status;
14754 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014755
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014756 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14757 TRACE_CODE_HDD_CFG80211_ADD_STA,
14758 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014759 mask = params->sta_flags_mask;
14760
14761 set = params->sta_flags_set;
14762
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014764 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14765 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014766
14767 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14768 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014769 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014770 }
14771 }
14772#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014773 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014774 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014775}
14776
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14778static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14779 struct net_device *dev, const u8 *mac,
14780 struct station_parameters *params)
14781#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014782static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14783 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014784#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014785{
14786 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014787
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014788 vos_ssr_protect(__func__);
14789 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14790 vos_ssr_unprotect(__func__);
14791
14792 return ret;
14793}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014794#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014795
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014796static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014797 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014798{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14800 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014801 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014802 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014803 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014804 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014806 ENTER();
14807
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014808 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014809 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014810 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014812 return -EINVAL;
14813 }
14814
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014815 if (!pmksa) {
14816 hddLog(LOGE, FL("pmksa is NULL"));
14817 return -EINVAL;
14818 }
14819
14820 if (!pmksa->bssid || !pmksa->pmkid) {
14821 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14822 pmksa->bssid, pmksa->pmkid);
14823 return -EINVAL;
14824 }
14825
14826 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14827 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14828
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14830 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014831 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014833 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014834 }
14835
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014836 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014837 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14838
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014839 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14840 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014841
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014842 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014843 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014844 &pmk_id, 1, FALSE);
14845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14847 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14848 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014850 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014851 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014852}
14853
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014854static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14855 struct cfg80211_pmksa *pmksa)
14856{
14857 int ret;
14858
14859 vos_ssr_protect(__func__);
14860 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14861 vos_ssr_unprotect(__func__);
14862
14863 return ret;
14864}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014865
Wilson Yang6507c4e2013-10-01 20:11:19 -070014866
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014867static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014868 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014869{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014870 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14871 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014872 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014873 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014874
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014875 ENTER();
14876
Wilson Yang6507c4e2013-10-01 20:11:19 -070014877 /* Validate pAdapter */
14878 if (NULL == pAdapter)
14879 {
14880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14881 return -EINVAL;
14882 }
14883
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014884 if (!pmksa) {
14885 hddLog(LOGE, FL("pmksa is NULL"));
14886 return -EINVAL;
14887 }
14888
14889 if (!pmksa->bssid) {
14890 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14891 return -EINVAL;
14892 }
14893
Kiet Lam98c46a12014-10-31 15:34:57 -070014894 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14895 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14896
Wilson Yang6507c4e2013-10-01 20:11:19 -070014897 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14898 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014899 if (0 != status)
14900 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014901 return status;
14902 }
14903
14904 /*Retrieve halHandle*/
14905 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14906
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14908 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14909 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014910 /* Delete the PMKID CSR cache */
14911 if (eHAL_STATUS_SUCCESS !=
14912 sme_RoamDelPMKIDfromCache(halHandle,
14913 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14914 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14915 MAC_ADDR_ARRAY(pmksa->bssid));
14916 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014917 }
14918
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014919 EXIT();
14920 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014921}
14922
Wilson Yang6507c4e2013-10-01 20:11:19 -070014923
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014924static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14925 struct cfg80211_pmksa *pmksa)
14926{
14927 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014928
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014929 vos_ssr_protect(__func__);
14930 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14931 vos_ssr_unprotect(__func__);
14932
14933 return ret;
14934
14935}
14936
14937static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014938{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014939 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14940 tHalHandle halHandle;
14941 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014942 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014943
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014944 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014945
14946 /* Validate pAdapter */
14947 if (NULL == pAdapter)
14948 {
14949 hddLog(VOS_TRACE_LEVEL_ERROR,
14950 "%s: Invalid Adapter" ,__func__);
14951 return -EINVAL;
14952 }
14953
14954 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14955 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014956 if (0 != status)
14957 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014958 return status;
14959 }
14960
14961 /*Retrieve halHandle*/
14962 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14963
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014964 /* Flush the PMKID cache in CSR */
14965 if (eHAL_STATUS_SUCCESS !=
14966 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14968 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014969 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014970 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014971 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014972}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014973
14974static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14975{
14976 int ret;
14977
14978 vos_ssr_protect(__func__);
14979 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14980 vos_ssr_unprotect(__func__);
14981
14982 return ret;
14983}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014984#endif
14985
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014986#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014987static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14988 struct net_device *dev,
14989 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014990{
14991 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14992 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014993 hdd_context_t *pHddCtx;
14994 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014995
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014996 ENTER();
14997
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014998 if (NULL == pAdapter)
14999 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015001 return -ENODEV;
15002 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015003 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15004 ret = wlan_hdd_validate_context(pHddCtx);
15005 if (0 != ret)
15006 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015007 return ret;
15008 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015009 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015010 if (NULL == pHddStaCtx)
15011 {
15012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15013 return -EINVAL;
15014 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015015
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015016 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15017 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15018 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015019 // Added for debug on reception of Re-assoc Req.
15020 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15021 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015022 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015023 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015024 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015025 }
15026
15027#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015028 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015029 ftie->ie_len);
15030#endif
15031
15032 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015033 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15034 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015035 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015036
15037 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015038 return 0;
15039}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015040
15041static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15042 struct net_device *dev,
15043 struct cfg80211_update_ft_ies_params *ftie)
15044{
15045 int ret;
15046
15047 vos_ssr_protect(__func__);
15048 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15049 vos_ssr_unprotect(__func__);
15050
15051 return ret;
15052}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015053#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015054
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015055#ifdef FEATURE_WLAN_SCAN_PNO
15056
15057void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15058 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15059{
15060 int ret;
15061 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15062 hdd_context_t *pHddCtx;
15063
Nirav Shah80830bf2013-12-31 16:35:12 +053015064 ENTER();
15065
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015066 if (NULL == pAdapter)
15067 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015069 "%s: HDD adapter is Null", __func__);
15070 return ;
15071 }
15072
15073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15074 if (NULL == pHddCtx)
15075 {
15076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15077 "%s: HDD context is Null!!!", __func__);
15078 return ;
15079 }
15080
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015081 spin_lock(&pHddCtx->schedScan_lock);
15082 if (TRUE == pHddCtx->isWiphySuspended)
15083 {
15084 pHddCtx->isSchedScanUpdatePending = TRUE;
15085 spin_unlock(&pHddCtx->schedScan_lock);
15086 hddLog(VOS_TRACE_LEVEL_INFO,
15087 "%s: Update cfg80211 scan database after it resume", __func__);
15088 return ;
15089 }
15090 spin_unlock(&pHddCtx->schedScan_lock);
15091
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015092 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15093
15094 if (0 > ret)
15095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15096
15097 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15099 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015100}
15101
15102/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015103 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015104 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015105 */
15106static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15107{
15108 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15109 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015110 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015111 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15112 int status = 0;
15113 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15114
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015115 /* The current firmware design does not allow PNO during any
15116 * active sessions. Hence, determine the active sessions
15117 * and return a failure.
15118 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015119 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15120 {
15121 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015122 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015123
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015124 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15125 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15126 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15127 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15128 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015129 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015130 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015131 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015132 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015133 }
15134 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15135 pAdapterNode = pNext;
15136 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015137 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015138}
15139
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015140void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15141{
15142 hdd_adapter_t *pAdapter = callbackContext;
15143 hdd_context_t *pHddCtx;
15144
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015145 ENTER();
15146
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015147 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15148 {
15149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15150 FL("Invalid adapter or adapter has invalid magic"));
15151 return;
15152 }
15153
15154 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15155 if (0 != wlan_hdd_validate_context(pHddCtx))
15156 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015157 return;
15158 }
15159
c_hpothub53c45d2014-08-18 16:53:14 +053015160 if (VOS_STATUS_SUCCESS != status)
15161 {
15162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015163 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015164 pHddCtx->isPnoEnable = FALSE;
15165 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015166
15167 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15168 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015169 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015170}
15171
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015172/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015173 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15174 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015175 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015176static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015177 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15178{
15179 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015180 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015181 hdd_context_t *pHddCtx;
15182 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015183 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015184 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15185 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015186 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15187 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015188 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015189 hdd_config_t *pConfig = NULL;
15190 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015192 ENTER();
15193
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015194 if (NULL == pAdapter)
15195 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015197 "%s: HDD adapter is Null", __func__);
15198 return -ENODEV;
15199 }
15200
15201 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015202 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015203
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015204 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015205 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015206 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015207 }
15208
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015209 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015210 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15211 if (NULL == hHal)
15212 {
15213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15214 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015215 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015216 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015217 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15218 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15219 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015220 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015221 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015222 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015223 {
15224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15225 "%s: aborting the existing scan is unsuccessfull", __func__);
15226 return -EBUSY;
15227 }
15228
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015229 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015230 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015232 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015233 return -EBUSY;
15234 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015235
c_hpothu37f21312014-04-09 21:49:54 +053015236 if (TRUE == pHddCtx->isPnoEnable)
15237 {
15238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15239 FL("already PNO is enabled"));
15240 return -EBUSY;
15241 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015242
15243 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15244 {
15245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15246 "%s: abort ROC failed ", __func__);
15247 return -EBUSY;
15248 }
15249
c_hpothu37f21312014-04-09 21:49:54 +053015250 pHddCtx->isPnoEnable = TRUE;
15251
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015252 pnoRequest.enable = 1; /*Enable PNO */
15253 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015254
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015255 if (( !pnoRequest.ucNetworksCount ) ||
15256 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015257 {
15258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015259 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015260 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015261 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015262 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015263 goto error;
15264 }
15265
15266 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15267 {
15268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015269 "%s: Incorrect number of channels %d",
15270 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015271 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015272 goto error;
15273 }
15274
15275 /* Framework provides one set of channels(all)
15276 * common for all saved profile */
15277 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15278 channels_allowed, &num_channels_allowed))
15279 {
15280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15281 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015282 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015283 goto error;
15284 }
15285 /* Checking each channel against allowed channel list */
15286 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015287 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015288 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015289 char chList [(request->n_channels*5)+1];
15290 int len;
15291 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015292 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015293 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015294 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015295 if (request->channels[i]->hw_value == channels_allowed[indx])
15296 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015297 if ((!pConfig->enableDFSPnoChnlScan) &&
15298 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15299 {
15300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15301 "%s : Dropping DFS channel : %d",
15302 __func__,channels_allowed[indx]);
15303 num_ignore_dfs_ch++;
15304 break;
15305 }
15306
Nirav Shah80830bf2013-12-31 16:35:12 +053015307 valid_ch[num_ch++] = request->channels[i]->hw_value;
15308 len += snprintf(chList+len, 5, "%d ",
15309 request->channels[i]->hw_value);
15310 break ;
15311 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015312 }
15313 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015314 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015315
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015316 /*If all channels are DFS and dropped, then ignore the PNO request*/
15317 if (num_ignore_dfs_ch == request->n_channels)
15318 {
15319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15320 "%s : All requested channels are DFS channels", __func__);
15321 ret = -EINVAL;
15322 goto error;
15323 }
15324 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015325
15326 pnoRequest.aNetworks =
15327 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15328 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015329 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015330 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15331 FL("failed to allocate memory aNetworks %u"),
15332 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15333 goto error;
15334 }
15335 vos_mem_zero(pnoRequest.aNetworks,
15336 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15337
15338 /* Filling per profile params */
15339 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15340 {
15341 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015342 request->match_sets[i].ssid.ssid_len;
15343
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015344 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15345 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015346 {
15347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015348 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015349 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015350 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015351 goto error;
15352 }
15353
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015354 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015355 request->match_sets[i].ssid.ssid,
15356 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15358 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015359 i, pnoRequest.aNetworks[i].ssId.ssId);
15360 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15361 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15362 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015363
15364 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015365 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15366 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015367
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015368 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015369 }
15370
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015371 for (i = 0; i < request->n_ssids; i++)
15372 {
15373 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015374 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015375 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015376 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015377 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015378 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015379 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015380 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015381 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015382 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015383 break;
15384 }
15385 j++;
15386 }
15387 }
15388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15389 "Number of hidden networks being Configured = %d",
15390 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015392 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015393
15394 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15395 if (pnoRequest.p24GProbeTemplate == NULL)
15396 {
15397 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15398 FL("failed to allocate memory p24GProbeTemplate %u"),
15399 SIR_PNO_MAX_PB_REQ_SIZE);
15400 goto error;
15401 }
15402
15403 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15404 if (pnoRequest.p5GProbeTemplate == NULL)
15405 {
15406 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15407 FL("failed to allocate memory p5GProbeTemplate %u"),
15408 SIR_PNO_MAX_PB_REQ_SIZE);
15409 goto error;
15410 }
15411
15412 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15413 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15414
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015415 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15416 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015417 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015418 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15419 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15420 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015421
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015422 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15423 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15424 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015425 }
15426
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015427 /* Driver gets only one time interval which is hardcoded in
15428 * supplicant for 10000ms. Taking power consumption into account 6 timers
15429 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15430 * 80,160,320 secs. And number of scan cycle for each timer
15431 * is configurable through INI param gPNOScanTimerRepeatValue.
15432 * If it is set to 0 only one timer will be used and PNO scan cycle
15433 * will be repeated after each interval specified by supplicant
15434 * till PNO is disabled.
15435 */
15436 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015437 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015438 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015439 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015440 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15441
15442 tempInterval = (request->interval)/1000;
15443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15444 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15445 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015446 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015447 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015448 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015449 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015450 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015451 tempInterval *= 2;
15452 }
15453 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015454 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015455
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015456 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015457
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015458 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015459 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15460 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015461 pAdapter->pno_req_status = 0;
15462
Nirav Shah80830bf2013-12-31 16:35:12 +053015463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15464 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015465 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15466 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015467
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015468 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015469 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015470 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15471 if (eHAL_STATUS_SUCCESS != status)
15472 {
15473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015474 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015475 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015476 goto error;
15477 }
15478
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015479 ret = wait_for_completion_timeout(
15480 &pAdapter->pno_comp_var,
15481 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15482 if (0 >= ret)
15483 {
15484 // Did not receive the response for PNO enable in time.
15485 // Assuming the PNO enable was success.
15486 // Returning error from here, because we timeout, results
15487 // in side effect of Wifi (Wifi Setting) not to work.
15488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15489 FL("Timed out waiting for PNO to be Enabled"));
15490 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015491 }
15492
15493 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015494 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015495
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015496error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15498 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015499 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015500 if (pnoRequest.aNetworks)
15501 vos_mem_free(pnoRequest.aNetworks);
15502 if (pnoRequest.p24GProbeTemplate)
15503 vos_mem_free(pnoRequest.p24GProbeTemplate);
15504 if (pnoRequest.p5GProbeTemplate)
15505 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015506
15507 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015508 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015509}
15510
15511/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015512 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15513 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015514 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015515static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15516 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15517{
15518 int ret;
15519
15520 vos_ssr_protect(__func__);
15521 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15522 vos_ssr_unprotect(__func__);
15523
15524 return ret;
15525}
15526
15527/*
15528 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15529 * Function to disable PNO
15530 */
15531static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015532 struct net_device *dev)
15533{
15534 eHalStatus status = eHAL_STATUS_FAILURE;
15535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15536 hdd_context_t *pHddCtx;
15537 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015538 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015539 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015540
15541 ENTER();
15542
15543 if (NULL == pAdapter)
15544 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015546 "%s: HDD adapter is Null", __func__);
15547 return -ENODEV;
15548 }
15549
15550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015551
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015552 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015553 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015555 "%s: HDD context is Null", __func__);
15556 return -ENODEV;
15557 }
15558
15559 /* The return 0 is intentional when isLogpInProgress and
15560 * isLoadUnloadInProgress. We did observe a crash due to a return of
15561 * failure in sched_scan_stop , especially for a case where the unload
15562 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15563 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15564 * success. If it returns a failure , then its next invocation due to the
15565 * clean up of the second interface will have the dev pointer corresponding
15566 * to the first one leading to a crash.
15567 */
15568 if (pHddCtx->isLogpInProgress)
15569 {
15570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15571 "%s: LOGP in Progress. Ignore!!!", __func__);
15572 return ret;
15573 }
15574
Mihir Shete18156292014-03-11 15:38:30 +053015575 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015576 {
15577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15578 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15579 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015580 }
15581
15582 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15583 if (NULL == hHal)
15584 {
15585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15586 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015587 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015588 }
15589
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015590 pnoRequest.enable = 0; /* Disable PNO */
15591 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015592
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015593 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15594 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15595 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015596 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015597 pAdapter->sessionId,
15598 NULL, pAdapter);
15599 if (eHAL_STATUS_SUCCESS != status)
15600 {
15601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15602 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015603 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015604 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015605 }
c_hpothu37f21312014-04-09 21:49:54 +053015606 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015607
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015608error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015610 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015611
15612 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015613 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015614}
15615
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015616/*
15617 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15618 * NL interface to disable PNO
15619 */
15620static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15621 struct net_device *dev)
15622{
15623 int ret;
15624
15625 vos_ssr_protect(__func__);
15626 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15627 vos_ssr_unprotect(__func__);
15628
15629 return ret;
15630}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015631#endif /*FEATURE_WLAN_SCAN_PNO*/
15632
15633
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015634#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015635#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015636static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15637 struct net_device *dev,
15638 u8 *peer, u8 action_code,
15639 u8 dialog_token,
15640 u16 status_code, u32 peer_capability,
15641 const u8 *buf, size_t len)
15642#else /* TDLS_MGMT_VERSION2 */
15643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15644static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15645 struct net_device *dev,
15646 const u8 *peer, u8 action_code,
15647 u8 dialog_token, u16 status_code,
15648 u32 peer_capability, bool initiator,
15649 const u8 *buf, size_t len)
15650#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15651static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15652 struct net_device *dev,
15653 const u8 *peer, u8 action_code,
15654 u8 dialog_token, u16 status_code,
15655 u32 peer_capability, const u8 *buf,
15656 size_t len)
15657#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15658static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15659 struct net_device *dev,
15660 u8 *peer, u8 action_code,
15661 u8 dialog_token,
15662 u16 status_code, u32 peer_capability,
15663 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015664#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015665static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15666 struct net_device *dev,
15667 u8 *peer, u8 action_code,
15668 u8 dialog_token,
15669 u16 status_code, const u8 *buf,
15670 size_t len)
15671#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015672#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015673{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015674 hdd_adapter_t *pAdapter;
15675 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015676 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015677 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015678 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015679 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015680 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015681#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015682 u32 peer_capability = 0;
15683#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015684 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015685 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015686
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015687 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15688 if (NULL == pAdapter)
15689 {
15690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15691 "%s: Adapter is NULL",__func__);
15692 return -EINVAL;
15693 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15695 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15696 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015697
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015698 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015699 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015702 "Invalid arguments");
15703 return -EINVAL;
15704 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015705
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015706 if (pHddCtx->isLogpInProgress)
15707 {
15708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15709 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015710 wlan_hdd_tdls_set_link_status(pAdapter,
15711 peer,
15712 eTDLS_LINK_IDLE,
15713 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015714 return -EBUSY;
15715 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015716
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015717 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15718 {
15719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15720 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15721 return -EAGAIN;
15722 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015723
Hoonki Lee27511902013-03-14 18:19:06 -070015724 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015725 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015727 "%s: TDLS mode is disabled OR not enabled in FW."
15728 MAC_ADDRESS_STR " action %d declined.",
15729 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015730 return -ENOTSUPP;
15731 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015732
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15734
15735 if( NULL == pHddStaCtx )
15736 {
15737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15738 "%s: HDD station context NULL ",__func__);
15739 return -EINVAL;
15740 }
15741
15742 /* STA should be connected and authenticated
15743 * before sending any TDLS frames
15744 */
15745 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15746 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15747 {
15748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15749 "STA is not connected or unauthenticated. "
15750 "connState %u, uIsAuthenticated %u",
15751 pHddStaCtx->conn_info.connState,
15752 pHddStaCtx->conn_info.uIsAuthenticated);
15753 return -EAGAIN;
15754 }
15755
Hoonki Lee27511902013-03-14 18:19:06 -070015756 /* other than teardown frame, other mgmt frames are not sent if disabled */
15757 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15758 {
15759 /* if tdls_mode is disabled to respond to peer's request */
15760 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15761 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015763 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015764 " TDLS mode is disabled. action %d declined.",
15765 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015766
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015767 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015768 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015769
15770 if (vos_max_concurrent_connections_reached())
15771 {
15772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15773 return -EINVAL;
15774 }
Hoonki Lee27511902013-03-14 18:19:06 -070015775 }
15776
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015777 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15778 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015779 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015780 {
15781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015782 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015783 " TDLS setup is ongoing. action %d declined.",
15784 __func__, MAC_ADDR_ARRAY(peer), action_code);
15785 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015786 }
15787 }
15788
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015789 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15790 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015791 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015792 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15793 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015794 {
15795 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15796 we return error code at 'add_station()'. Hence we have this
15797 check again in addtion to add_station().
15798 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015799 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015800 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15802 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015803 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15804 __func__, MAC_ADDR_ARRAY(peer), action_code,
15805 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015806 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015807 }
15808 else
15809 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015810 /* maximum reached. tweak to send error code to peer and return
15811 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015812 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15814 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015815 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15816 __func__, MAC_ADDR_ARRAY(peer), status_code,
15817 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015818 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015819 /* fall through to send setup resp with failure status
15820 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015821 }
15822 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015823 else
15824 {
15825 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015826 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015827 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015828 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015830 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15831 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015832 return -EPERM;
15833 }
15834 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015835 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015836
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015838 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015839 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15840 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015841
Hoonki Leea34dd892013-02-05 22:56:02 -080015842 /*Except teardown responder will not be used so just make 0*/
15843 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015844 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015845 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015846
15847 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015848 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015849
15850 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15851 responder = pTdlsPeer->is_responder;
15852 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015853 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015855 "%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 -070015856 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15857 dialog_token, status_code, len);
15858 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015859 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015860 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015861
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015862 /* For explicit trigger of DIS_REQ come out of BMPS for
15863 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015864 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015865 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15866 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015867 {
15868 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15869 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015871 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015872 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15873 if (status != VOS_STATUS_SUCCESS) {
15874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15875 }
Hoonki Lee14621352013-04-16 17:51:19 -070015876 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015877 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015878 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15880 }
15881 }
Hoonki Lee14621352013-04-16 17:51:19 -070015882 }
15883
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015884 /* make sure doesn't call send_mgmt() while it is pending */
15885 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15886 {
15887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015888 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015889 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015890 ret = -EBUSY;
15891 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015892 }
15893
15894 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015895 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15896
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015897 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15898 pAdapter->sessionId, peer, action_code, dialog_token,
15899 status_code, peer_capability, (tANI_U8 *)buf, len,
15900 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015901
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015902 if (VOS_STATUS_SUCCESS != status)
15903 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15905 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015906 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015907 ret = -EINVAL;
15908 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015909 }
15910
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015911 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15912 (SIR_MAC_TDLS_DIS_RSP == action_code))
15913 {
15914 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15915 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15916 */
15917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15918 "%s: tx done for frm %u", __func__, action_code);
15919 return 0;
15920 }
15921
15922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15923 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15924 WAIT_TIME_TDLS_MGMT);
15925
Hoonki Leed37cbb32013-04-20 00:31:14 -070015926 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15927 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15928
15929 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015930 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015932 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015933 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015934 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015935
15936 if (pHddCtx->isLogpInProgress)
15937 {
15938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15939 "%s: LOGP in Progress. Ignore!!!", __func__);
15940 return -EAGAIN;
15941 }
15942
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015943 ret = -EINVAL;
15944 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015945 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015946 else
15947 {
15948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15949 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15950 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15951 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015952
Gopichand Nakkala05922802013-03-14 12:23:19 -070015953 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015954 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015955 ret = max_sta_failed;
15956 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015957 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015958
Hoonki Leea34dd892013-02-05 22:56:02 -080015959 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15960 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015961 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15963 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015964 }
15965 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15966 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015967 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015968 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15969 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015970 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015971
15972 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015973
15974tx_failed:
15975 /* add_station will be called before sending TDLS_SETUP_REQ and
15976 * TDLS_SETUP_RSP and as part of add_station driver will enable
15977 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15978 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15979 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15980 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15981 */
15982
15983 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15984 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15985 wlan_hdd_tdls_check_bmps(pAdapter);
15986 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015987}
15988
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015989#if TDLS_MGMT_VERSION2
15990static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15991 u8 *peer, u8 action_code, u8 dialog_token,
15992 u16 status_code, u32 peer_capability,
15993 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015994#else /* TDLS_MGMT_VERSION2 */
15995#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15996static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15997 struct net_device *dev,
15998 const u8 *peer, u8 action_code,
15999 u8 dialog_token, u16 status_code,
16000 u32 peer_capability, bool initiator,
16001 const u8 *buf, size_t len)
16002#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16003static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16004 struct net_device *dev,
16005 const u8 *peer, u8 action_code,
16006 u8 dialog_token, u16 status_code,
16007 u32 peer_capability, const u8 *buf,
16008 size_t len)
16009#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16010static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16011 struct net_device *dev,
16012 u8 *peer, u8 action_code,
16013 u8 dialog_token,
16014 u16 status_code, u32 peer_capability,
16015 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016016#else
16017static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16018 u8 *peer, u8 action_code, u8 dialog_token,
16019 u16 status_code, const u8 *buf, size_t len)
16020#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016021#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016022{
16023 int ret;
16024
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016025 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016026#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016027 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16028 dialog_token, status_code,
16029 peer_capability, buf, len);
16030#else /* TDLS_MGMT_VERSION2 */
16031#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16032 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16033 dialog_token, status_code,
16034 peer_capability, initiator,
16035 buf, len);
16036#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16037 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16038 dialog_token, status_code,
16039 peer_capability, buf, len);
16040#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16041 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16042 dialog_token, status_code,
16043 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016044#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016045 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16046 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016047#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016048#endif
16049 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016050
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016051 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016052}
Atul Mittal115287b2014-07-08 13:26:33 +053016053
16054int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16056 const u8 *peer,
16057#else
Atul Mittal115287b2014-07-08 13:26:33 +053016058 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016059#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016060 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016061 cfg80211_exttdls_callback callback)
16062{
16063
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016064 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016066 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16068 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16069 __func__, MAC_ADDR_ARRAY(peer));
16070
16071 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16072 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16073
16074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016075 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16076 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16077 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016078 return -ENOTSUPP;
16079 }
16080
16081 /* To cater the requirement of establishing the TDLS link
16082 * irrespective of the data traffic , get an entry of TDLS peer.
16083 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016084 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016085 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16086 if (pTdlsPeer == NULL) {
16087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16088 "%s: peer " MAC_ADDRESS_STR " not existing",
16089 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016090 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016091 return -EINVAL;
16092 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016093 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016094
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016095 /* check FW TDLS Off Channel capability */
16096 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016097 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016098 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016099 {
16100 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16101 pTdlsPeer->peerParams.global_operating_class =
16102 tdls_peer_params->global_operating_class;
16103 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16104 pTdlsPeer->peerParams.min_bandwidth_kbps =
16105 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016106 /* check configured channel is valid, non dfs and
16107 * not current operating channel */
16108 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16109 tdls_peer_params->channel)) &&
16110 (pHddStaCtx) &&
16111 (tdls_peer_params->channel !=
16112 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016113 {
16114 pTdlsPeer->isOffChannelConfigured = TRUE;
16115 }
16116 else
16117 {
16118 pTdlsPeer->isOffChannelConfigured = FALSE;
16119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16120 "%s: Configured Tdls Off Channel is not valid", __func__);
16121
16122 }
16123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016124 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16125 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016126 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016127 pTdlsPeer->isOffChannelConfigured,
16128 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016129 }
16130 else
16131 {
16132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016133 "%s: TDLS off channel FW capability %d, "
16134 "host capab %d or Invalid TDLS Peer Params", __func__,
16135 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16136 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016137 }
16138
Atul Mittal115287b2014-07-08 13:26:33 +053016139 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16140
16141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16142 " %s TDLS Add Force Peer Failed",
16143 __func__);
16144 return -EINVAL;
16145 }
16146 /*EXT TDLS*/
16147
16148 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16150 " %s TDLS set callback Failed",
16151 __func__);
16152 return -EINVAL;
16153 }
16154
16155 return(0);
16156
16157}
16158
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016159int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16161 const u8 *peer
16162#else
16163 u8 *peer
16164#endif
16165)
Atul Mittal115287b2014-07-08 13:26:33 +053016166{
16167
16168 hddTdlsPeer_t *pTdlsPeer;
16169 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16171 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16172 __func__, MAC_ADDR_ARRAY(peer));
16173
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016174 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16176 return -EINVAL;
16177 }
16178
Atul Mittal115287b2014-07-08 13:26:33 +053016179 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16180 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16181
16182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016183 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16184 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16185 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016186 return -ENOTSUPP;
16187 }
16188
16189
16190 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16191
16192 if ( NULL == pTdlsPeer ) {
16193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016194 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016195 __func__, MAC_ADDR_ARRAY(peer));
16196 return -EINVAL;
16197 }
16198 else {
16199 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16200 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016201 /* if channel switch is configured, reset
16202 the channel for this peer */
16203 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16204 {
16205 pTdlsPeer->peerParams.channel = 0;
16206 pTdlsPeer->isOffChannelConfigured = FALSE;
16207 }
Atul Mittal115287b2014-07-08 13:26:33 +053016208 }
16209
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016210 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016212 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016213 }
Atul Mittal115287b2014-07-08 13:26:33 +053016214
16215 /*EXT TDLS*/
16216
16217 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16218
16219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16220 " %s TDLS set callback Failed",
16221 __func__);
16222 return -EINVAL;
16223 }
16224 return(0);
16225
16226}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016227static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16229 const u8 *peer,
16230#else
16231 u8 *peer,
16232#endif
16233 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016234{
16235 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16236 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016237 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016238 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016240 ENTER();
16241
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016242 if (!pAdapter) {
16243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16244 return -EINVAL;
16245 }
16246
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016247 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16248 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16249 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016250 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016251 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016253 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016254 return -EINVAL;
16255 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016256
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016257 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016258 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016259 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016260 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016261 }
16262
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016263
16264 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016265 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016266 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016268 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16269 "Cannot process TDLS commands",
16270 pHddCtx->cfg_ini->fEnableTDLSSupport,
16271 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016272 return -ENOTSUPP;
16273 }
16274
16275 switch (oper) {
16276 case NL80211_TDLS_ENABLE_LINK:
16277 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016278 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016279 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016280 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016281 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016282 tANI_U16 numCurrTdlsPeers = 0;
16283 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016284 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016285
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16287 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16288 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016289 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016290 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016291 if ( NULL == pTdlsPeer ) {
16292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16293 " (oper %d) not exsting. ignored",
16294 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16295 return -EINVAL;
16296 }
16297
16298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16299 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16300 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16301 "NL80211_TDLS_ENABLE_LINK");
16302
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016303 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16304 {
16305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16306 MAC_ADDRESS_STR " failed",
16307 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16308 return -EINVAL;
16309 }
16310
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016311 /* before starting tdls connection, set tdls
16312 * off channel established status to default value */
16313 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016314 /* TDLS Off Channel, Disable tdls channel switch,
16315 when there are more than one tdls link */
16316 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016317 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016318 {
16319 /* get connected peer and send disable tdls off chan */
16320 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016321 if ((connPeer) &&
16322 (connPeer->isOffChannelSupported == TRUE) &&
16323 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016324 {
16325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16326 "%s: More then one peer connected, Disable "
16327 "TDLS channel switch", __func__);
16328
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016329 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016330 ret = sme_SendTdlsChanSwitchReq(
16331 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016332 pAdapter->sessionId,
16333 connPeer->peerMac,
16334 connPeer->peerParams.channel,
16335 TDLS_OFF_CHANNEL_BW_OFFSET,
16336 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016337 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016338 hddLog(VOS_TRACE_LEVEL_ERROR,
16339 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016340 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016341 }
16342 else
16343 {
16344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16345 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016346 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016347 "isOffChannelConfigured %d",
16348 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016349 (connPeer ? (connPeer->isOffChannelSupported)
16350 : -1),
16351 (connPeer ? (connPeer->isOffChannelConfigured)
16352 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016353 }
16354 }
16355
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016356 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016357 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016358 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016359
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016360 if (0 != wlan_hdd_tdls_get_link_establish_params(
16361 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016363 return -EINVAL;
16364 }
16365 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016366
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016367 ret = sme_SendTdlsLinkEstablishParams(
16368 WLAN_HDD_GET_HAL_CTX(pAdapter),
16369 pAdapter->sessionId, peer,
16370 &tdlsLinkEstablishParams);
16371 if (ret != VOS_STATUS_SUCCESS) {
16372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16373 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016374 /* Send TDLS peer UAPSD capabilities to the firmware and
16375 * register with the TL on after the response for this operation
16376 * is received .
16377 */
16378 ret = wait_for_completion_interruptible_timeout(
16379 &pAdapter->tdls_link_establish_req_comp,
16380 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16381 if (ret <= 0)
16382 {
16383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016384 FL("Link Establish Request Failed Status %ld"),
16385 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016386 return -EINVAL;
16387 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016388 }
Atul Mittal115287b2014-07-08 13:26:33 +053016389 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16390 eTDLS_LINK_CONNECTED,
16391 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016392 staDesc.ucSTAId = pTdlsPeer->staId;
16393 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016394 ret = WLANTL_UpdateTdlsSTAClient(
16395 pHddCtx->pvosContext,
16396 &staDesc);
16397 if (ret != VOS_STATUS_SUCCESS) {
16398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16399 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016400
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016401 /* Mark TDLS client Authenticated .*/
16402 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16403 pTdlsPeer->staId,
16404 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016405 if (VOS_STATUS_SUCCESS == status)
16406 {
Hoonki Lee14621352013-04-16 17:51:19 -070016407 if (pTdlsPeer->is_responder == 0)
16408 {
16409 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016410 tdlsConnInfo_t *tdlsInfo;
16411
16412 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16413
16414 /* Initialize initiator wait callback */
16415 vos_timer_init(
16416 &pTdlsPeer->initiatorWaitTimeoutTimer,
16417 VOS_TIMER_TYPE_SW,
16418 wlan_hdd_tdls_initiator_wait_cb,
16419 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016420
16421 wlan_hdd_tdls_timer_restart(pAdapter,
16422 &pTdlsPeer->initiatorWaitTimeoutTimer,
16423 WAIT_TIME_TDLS_INITIATOR);
16424 /* suspend initiator TX until it receives direct packet from the
16425 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016426 ret = WLANTL_SuspendDataTx(
16427 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16428 &staId, NULL);
16429 if (ret != VOS_STATUS_SUCCESS) {
16430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16431 }
Hoonki Lee14621352013-04-16 17:51:19 -070016432 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016433
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016434 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016435 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016436 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016437 suppChannelLen =
16438 tdlsLinkEstablishParams.supportedChannelsLen;
16439
16440 if ((suppChannelLen > 0) &&
16441 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16442 {
16443 tANI_U8 suppPeerChannel = 0;
16444 int i = 0;
16445 for (i = 0U; i < suppChannelLen; i++)
16446 {
16447 suppPeerChannel =
16448 tdlsLinkEstablishParams.supportedChannels[i];
16449
16450 pTdlsPeer->isOffChannelSupported = FALSE;
16451 if (suppPeerChannel ==
16452 pTdlsPeer->peerParams.channel)
16453 {
16454 pTdlsPeer->isOffChannelSupported = TRUE;
16455 break;
16456 }
16457 }
16458 }
16459 else
16460 {
16461 pTdlsPeer->isOffChannelSupported = FALSE;
16462 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016463 }
16464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16465 "%s: TDLS channel switch request for channel "
16466 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016467 "%d isOffChannelSupported %d", __func__,
16468 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016469 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016470 suppChannelLen,
16471 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016472
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016473 /* TDLS Off Channel, Enable tdls channel switch,
16474 when their is only one tdls link and it supports */
16475 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16476 if ((numCurrTdlsPeers == 1) &&
16477 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16478 (TRUE == pTdlsPeer->isOffChannelConfigured))
16479 {
16480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16481 "%s: Send TDLS channel switch request for channel %d",
16482 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016483
16484 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016485 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16486 pAdapter->sessionId,
16487 pTdlsPeer->peerMac,
16488 pTdlsPeer->peerParams.channel,
16489 TDLS_OFF_CHANNEL_BW_OFFSET,
16490 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016491 if (ret != VOS_STATUS_SUCCESS) {
16492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16493 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016494 }
16495 else
16496 {
16497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16498 "%s: TDLS channel switch request not sent"
16499 " numCurrTdlsPeers %d "
16500 "isOffChannelSupported %d "
16501 "isOffChannelConfigured %d",
16502 __func__, numCurrTdlsPeers,
16503 pTdlsPeer->isOffChannelSupported,
16504 pTdlsPeer->isOffChannelConfigured);
16505 }
16506
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016507 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016508 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016509
16510 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016511 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16512 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016513 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016514 int ac;
16515 uint8 ucAc[4] = { WLANTL_AC_VO,
16516 WLANTL_AC_VI,
16517 WLANTL_AC_BK,
16518 WLANTL_AC_BE };
16519 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16520 for(ac=0; ac < 4; ac++)
16521 {
16522 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16523 pTdlsPeer->staId, ucAc[ac],
16524 tlTid[ac], tlTid[ac], 0, 0,
16525 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016526 if (status != VOS_STATUS_SUCCESS) {
16527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16528 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016529 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016530 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016531 }
16532
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016533 }
16534 break;
16535 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016536 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016537 tANI_U16 numCurrTdlsPeers = 0;
16538 hddTdlsPeer_t *connPeer = NULL;
16539
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16541 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16542 __func__, MAC_ADDR_ARRAY(peer));
16543
Sunil Dutt41de4e22013-11-14 18:09:02 +053016544 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16545
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016546
Sunil Dutt41de4e22013-11-14 18:09:02 +053016547 if ( NULL == pTdlsPeer ) {
16548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16549 " (oper %d) not exsting. ignored",
16550 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16551 return -EINVAL;
16552 }
16553
16554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16555 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16556 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16557 "NL80211_TDLS_DISABLE_LINK");
16558
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016559 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016560 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016561 long status;
16562
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016563 /* set tdls off channel status to false for this peer */
16564 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016565 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16566 eTDLS_LINK_TEARING,
16567 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16568 eTDLS_LINK_UNSPECIFIED:
16569 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016570 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16571
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016572 status = sme_DeleteTdlsPeerSta(
16573 WLAN_HDD_GET_HAL_CTX(pAdapter),
16574 pAdapter->sessionId, peer );
16575 if (status != VOS_STATUS_SUCCESS) {
16576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16577 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016578
16579 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16580 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016581 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016582 eTDLS_LINK_IDLE,
16583 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016584 if (status <= 0)
16585 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16587 "%s: Del station failed status %ld",
16588 __func__, status);
16589 return -EPERM;
16590 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016591
16592 /* TDLS Off Channel, Enable tdls channel switch,
16593 when their is only one tdls link and it supports */
16594 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16595 if (numCurrTdlsPeers == 1)
16596 {
16597 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16598 if ((connPeer) &&
16599 (connPeer->isOffChannelSupported == TRUE) &&
16600 (connPeer->isOffChannelConfigured == TRUE))
16601 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016602 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016603 status = sme_SendTdlsChanSwitchReq(
16604 WLAN_HDD_GET_HAL_CTX(pAdapter),
16605 pAdapter->sessionId,
16606 connPeer->peerMac,
16607 connPeer->peerParams.channel,
16608 TDLS_OFF_CHANNEL_BW_OFFSET,
16609 TDLS_CHANNEL_SWITCH_ENABLE);
16610 if (status != VOS_STATUS_SUCCESS) {
16611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16612 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016613 }
16614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16615 "%s: TDLS channel switch "
16616 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016617 "isOffChannelConfigured %d "
16618 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016619 __func__,
16620 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016621 (connPeer ? connPeer->isOffChannelConfigured : -1),
16622 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016623 }
16624 else
16625 {
16626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16627 "%s: TDLS channel switch request not sent "
16628 "numCurrTdlsPeers %d ",
16629 __func__, numCurrTdlsPeers);
16630 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016631 }
16632 else
16633 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16635 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016636 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016637 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016638 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016639 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016640 {
Atul Mittal115287b2014-07-08 13:26:33 +053016641 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016642
Atul Mittal115287b2014-07-08 13:26:33 +053016643 if (0 != status)
16644 {
16645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016646 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016647 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016648 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016649 break;
16650 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016651 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016652 {
Atul Mittal115287b2014-07-08 13:26:33 +053016653 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16654 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016655 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016656 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016657
Atul Mittal115287b2014-07-08 13:26:33 +053016658 if (0 != status)
16659 {
16660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016661 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016662 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016663 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016664 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016665 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016666 case NL80211_TDLS_DISCOVERY_REQ:
16667 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016669 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016670 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016671 return -ENOTSUPP;
16672 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16674 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016675 return -ENOTSUPP;
16676 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016677
16678 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016679 return 0;
16680}
Chilam NG571c65a2013-01-19 12:27:36 +053016681
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016682static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16684 const u8 *peer,
16685#else
16686 u8 *peer,
16687#endif
16688 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016689{
16690 int ret;
16691
16692 vos_ssr_protect(__func__);
16693 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16694 vos_ssr_unprotect(__func__);
16695
16696 return ret;
16697}
16698
Chilam NG571c65a2013-01-19 12:27:36 +053016699int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16700 struct net_device *dev, u8 *peer)
16701{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016702 hddLog(VOS_TRACE_LEVEL_INFO,
16703 "tdls send discover req: "MAC_ADDRESS_STR,
16704 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016705
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016706#if TDLS_MGMT_VERSION2
16707 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16708 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16709#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16711 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16712 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16713#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16714 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16715 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16716#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16717 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16718 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16719#else
Chilam NG571c65a2013-01-19 12:27:36 +053016720 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16721 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016722#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016723#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016724}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016725#endif
16726
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016727#ifdef WLAN_FEATURE_GTK_OFFLOAD
16728/*
16729 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16730 * Callback rountine called upon receiving response for
16731 * get offload info
16732 */
16733void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16734 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16735{
16736
16737 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016738 tANI_U8 tempReplayCounter[8];
16739 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016740
16741 ENTER();
16742
16743 if (NULL == pAdapter)
16744 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016746 "%s: HDD adapter is Null", __func__);
16747 return ;
16748 }
16749
16750 if (NULL == pGtkOffloadGetInfoRsp)
16751 {
16752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16753 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16754 return ;
16755 }
16756
16757 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16758 {
16759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16760 "%s: wlan Failed to get replay counter value",
16761 __func__);
16762 return ;
16763 }
16764
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16766 /* Update replay counter */
16767 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16768 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16769
16770 {
16771 /* changing from little to big endian since supplicant
16772 * works on big endian format
16773 */
16774 int i;
16775 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16776
16777 for (i = 0; i < 8; i++)
16778 {
16779 tempReplayCounter[7-i] = (tANI_U8)p[i];
16780 }
16781 }
16782
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016783 /* Update replay counter to NL */
16784 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016785 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016786}
16787
16788/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016789 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016790 * This function is used to offload GTK rekeying job to the firmware.
16791 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016792int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016793 struct cfg80211_gtk_rekey_data *data)
16794{
16795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16796 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16797 hdd_station_ctx_t *pHddStaCtx;
16798 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016799 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016800 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016801 eHalStatus status = eHAL_STATUS_FAILURE;
16802
16803 ENTER();
16804
16805 if (NULL == pAdapter)
16806 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016808 "%s: HDD adapter is Null", __func__);
16809 return -ENODEV;
16810 }
16811
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16813 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16814 pAdapter->sessionId, pAdapter->device_mode));
16815
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016816 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016817 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016818 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016819 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016820 }
16821
16822 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16823 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16824 if (NULL == hHal)
16825 {
16826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16827 "%s: HAL context is Null!!!", __func__);
16828 return -EAGAIN;
16829 }
16830
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016831 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16832 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16833 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16834 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016835 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016836 {
16837 /* changing from big to little endian since driver
16838 * works on little endian format
16839 */
16840 tANI_U8 *p =
16841 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16842 int i;
16843
16844 for (i = 0; i < 8; i++)
16845 {
16846 p[7-i] = data->replay_ctr[i];
16847 }
16848 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016849
16850 if (TRUE == pHddCtx->hdd_wlan_suspended)
16851 {
16852 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016853 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16854 sizeof (tSirGtkOffloadParams));
16855 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016856 pAdapter->sessionId);
16857
16858 if (eHAL_STATUS_SUCCESS != status)
16859 {
16860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16861 "%s: sme_SetGTKOffload failed, returned %d",
16862 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016863
16864 /* Need to clear any trace of key value in the memory.
16865 * Thus zero out the memory even though it is local
16866 * variable.
16867 */
16868 vos_mem_zero(&hddGtkOffloadReqParams,
16869 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016870 return status;
16871 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16873 "%s: sme_SetGTKOffload successfull", __func__);
16874 }
16875 else
16876 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16878 "%s: wlan not suspended GTKOffload request is stored",
16879 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016880 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016881
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016882 /* Need to clear any trace of key value in the memory.
16883 * Thus zero out the memory even though it is local
16884 * variable.
16885 */
16886 vos_mem_zero(&hddGtkOffloadReqParams,
16887 sizeof(hddGtkOffloadReqParams));
16888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016889 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016890 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016891}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016892
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016893int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16894 struct cfg80211_gtk_rekey_data *data)
16895{
16896 int ret;
16897
16898 vos_ssr_protect(__func__);
16899 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16900 vos_ssr_unprotect(__func__);
16901
16902 return ret;
16903}
16904#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016905/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016906 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016907 * This function is used to set access control policy
16908 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016909static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16910 struct net_device *dev,
16911 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016912{
16913 int i;
16914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16915 hdd_hostapd_state_t *pHostapdState;
16916 tsap_Config_t *pConfig;
16917 v_CONTEXT_t pVosContext = NULL;
16918 hdd_context_t *pHddCtx;
16919 int status;
16920
16921 ENTER();
16922
16923 if (NULL == pAdapter)
16924 {
16925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16926 "%s: HDD adapter is Null", __func__);
16927 return -ENODEV;
16928 }
16929
16930 if (NULL == params)
16931 {
16932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16933 "%s: params is Null", __func__);
16934 return -EINVAL;
16935 }
16936
16937 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16938 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016939 if (0 != status)
16940 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016941 return status;
16942 }
16943
16944 pVosContext = pHddCtx->pvosContext;
16945 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16946
16947 if (NULL == pHostapdState)
16948 {
16949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16950 "%s: pHostapdState is Null", __func__);
16951 return -EINVAL;
16952 }
16953
16954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16955 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16957 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16958 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016959
16960 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16961 {
16962 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16963
16964 /* default value */
16965 pConfig->num_accept_mac = 0;
16966 pConfig->num_deny_mac = 0;
16967
16968 /**
16969 * access control policy
16970 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16971 * listed in hostapd.deny file.
16972 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16973 * listed in hostapd.accept file.
16974 */
16975 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16976 {
16977 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16978 }
16979 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16980 {
16981 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16982 }
16983 else
16984 {
16985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16986 "%s:Acl Policy : %d is not supported",
16987 __func__, params->acl_policy);
16988 return -ENOTSUPP;
16989 }
16990
16991 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16992 {
16993 pConfig->num_accept_mac = params->n_acl_entries;
16994 for (i = 0; i < params->n_acl_entries; i++)
16995 {
16996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16997 "** Add ACL MAC entry %i in WhiletList :"
16998 MAC_ADDRESS_STR, i,
16999 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17000
17001 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17002 sizeof(qcmacaddr));
17003 }
17004 }
17005 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17006 {
17007 pConfig->num_deny_mac = params->n_acl_entries;
17008 for (i = 0; i < params->n_acl_entries; i++)
17009 {
17010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17011 "** Add ACL MAC entry %i in BlackList :"
17012 MAC_ADDRESS_STR, i,
17013 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17014
17015 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17016 sizeof(qcmacaddr));
17017 }
17018 }
17019
17020 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17021 {
17022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17023 "%s: SAP Set Mac Acl fail", __func__);
17024 return -EINVAL;
17025 }
17026 }
17027 else
17028 {
17029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017030 "%s: Invalid device_mode = %s (%d)",
17031 __func__, hdd_device_modetoString(pAdapter->device_mode),
17032 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017033 return -EINVAL;
17034 }
17035
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017036 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017037 return 0;
17038}
17039
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017040static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17041 struct net_device *dev,
17042 const struct cfg80211_acl_data *params)
17043{
17044 int ret;
17045 vos_ssr_protect(__func__);
17046 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17047 vos_ssr_unprotect(__func__);
17048
17049 return ret;
17050}
17051
Leo Chang9056f462013-08-01 19:21:11 -070017052#ifdef WLAN_NL80211_TESTMODE
17053#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017054void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017055(
17056 void *pAdapter,
17057 void *indCont
17058)
17059{
Leo Changd9df8aa2013-09-26 13:32:26 -070017060 tSirLPHBInd *lphbInd;
17061 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017062 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017063
17064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017065 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017066
c_hpothu73f35e62014-04-18 13:40:08 +053017067 if (pAdapter == NULL)
17068 {
17069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17070 "%s: pAdapter is NULL\n",__func__);
17071 return;
17072 }
17073
Leo Chang9056f462013-08-01 19:21:11 -070017074 if (NULL == indCont)
17075 {
17076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017077 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017078 return;
17079 }
17080
c_hpothu73f35e62014-04-18 13:40:08 +053017081 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017082 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017083 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017084 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017085 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017086 GFP_ATOMIC);
17087 if (!skb)
17088 {
17089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17090 "LPHB timeout, NL buffer alloc fail");
17091 return;
17092 }
17093
Leo Changac3ba772013-10-07 09:47:04 -070017094 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017095 {
17096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17097 "WLAN_HDD_TM_ATTR_CMD put fail");
17098 goto nla_put_failure;
17099 }
Leo Changac3ba772013-10-07 09:47:04 -070017100 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017101 {
17102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17103 "WLAN_HDD_TM_ATTR_TYPE put fail");
17104 goto nla_put_failure;
17105 }
Leo Changac3ba772013-10-07 09:47:04 -070017106 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017107 sizeof(tSirLPHBInd), lphbInd))
17108 {
17109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17110 "WLAN_HDD_TM_ATTR_DATA put fail");
17111 goto nla_put_failure;
17112 }
Leo Chang9056f462013-08-01 19:21:11 -070017113 cfg80211_testmode_event(skb, GFP_ATOMIC);
17114 return;
17115
17116nla_put_failure:
17117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17118 "NLA Put fail");
17119 kfree_skb(skb);
17120
17121 return;
17122}
17123#endif /* FEATURE_WLAN_LPHB */
17124
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017125static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017126{
17127 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17128 int err = 0;
17129#ifdef FEATURE_WLAN_LPHB
17130 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017131 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017132
17133 ENTER();
17134
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017135 err = wlan_hdd_validate_context(pHddCtx);
17136 if (0 != err)
17137 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017138 return err;
17139 }
Leo Chang9056f462013-08-01 19:21:11 -070017140#endif /* FEATURE_WLAN_LPHB */
17141
17142 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17143 if (err)
17144 {
17145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17146 "%s Testmode INV ATTR", __func__);
17147 return err;
17148 }
17149
17150 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17151 {
17152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17153 "%s Testmode INV CMD", __func__);
17154 return -EINVAL;
17155 }
17156
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17158 TRACE_CODE_HDD_CFG80211_TESTMODE,
17159 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017160 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17161 {
17162#ifdef FEATURE_WLAN_LPHB
17163 /* Low Power Heartbeat configuration request */
17164 case WLAN_HDD_TM_CMD_WLAN_HB:
17165 {
17166 int buf_len;
17167 void *buf;
17168 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017169 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017170
17171 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17172 {
17173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17174 "%s Testmode INV DATA", __func__);
17175 return -EINVAL;
17176 }
17177
17178 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17179 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017180
17181 hb_params_temp =(tSirLPHBReq *)buf;
17182 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17183 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17184 return -EINVAL;
17185
Leo Chang9056f462013-08-01 19:21:11 -070017186 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17187 if (NULL == hb_params)
17188 {
17189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17190 "%s Request Buffer Alloc Fail", __func__);
17191 return -EINVAL;
17192 }
17193
17194 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017195 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17196 hb_params,
17197 wlan_hdd_cfg80211_lphb_ind_handler);
17198 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017199 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17201 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017202 vos_mem_free(hb_params);
17203 }
Leo Chang9056f462013-08-01 19:21:11 -070017204 return 0;
17205 }
17206#endif /* FEATURE_WLAN_LPHB */
17207 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17209 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017210 return -EOPNOTSUPP;
17211 }
17212
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017213 EXIT();
17214 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017215}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017216
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017217static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17219 struct wireless_dev *wdev,
17220#endif
17221 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017222{
17223 int ret;
17224
17225 vos_ssr_protect(__func__);
17226 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17227 vos_ssr_unprotect(__func__);
17228
17229 return ret;
17230}
Leo Chang9056f462013-08-01 19:21:11 -070017231#endif /* CONFIG_NL80211_TESTMODE */
17232
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017233static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017234 struct net_device *dev,
17235 int idx, struct survey_info *survey)
17236{
17237 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17238 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017239 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017240 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017241 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017242 v_S7_t snr,rssi;
17243 int status, i, j, filled = 0;
17244
17245 ENTER();
17246
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017247 if (NULL == pAdapter)
17248 {
17249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17250 "%s: HDD adapter is Null", __func__);
17251 return -ENODEV;
17252 }
17253
17254 if (NULL == wiphy)
17255 {
17256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17257 "%s: wiphy is Null", __func__);
17258 return -ENODEV;
17259 }
17260
17261 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17262 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017263 if (0 != status)
17264 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017265 return status;
17266 }
17267
Mihir Sheted9072e02013-08-21 17:02:29 +053017268 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17269
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017270 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017271 0 != pAdapter->survey_idx ||
17272 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017273 {
17274 /* The survey dump ops when implemented completely is expected to
17275 * return a survey of all channels and the ops is called by the
17276 * kernel with incremental values of the argument 'idx' till it
17277 * returns -ENONET. But we can only support the survey for the
17278 * operating channel for now. survey_idx is used to track
17279 * that the ops is called only once and then return -ENONET for
17280 * the next iteration
17281 */
17282 pAdapter->survey_idx = 0;
17283 return -ENONET;
17284 }
17285
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017286 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17287 {
17288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17289 "%s: Roaming in progress, hence return ", __func__);
17290 return -ENONET;
17291 }
17292
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017293 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17294
17295 wlan_hdd_get_snr(pAdapter, &snr);
17296 wlan_hdd_get_rssi(pAdapter, &rssi);
17297
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017298 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17299 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17300 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017301 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17302 hdd_wlan_get_freq(channel, &freq);
17303
17304
17305 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17306 {
17307 if (NULL == wiphy->bands[i])
17308 {
17309 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17310 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17311 continue;
17312 }
17313
17314 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17315 {
17316 struct ieee80211_supported_band *band = wiphy->bands[i];
17317
17318 if (band->channels[j].center_freq == (v_U16_t)freq)
17319 {
17320 survey->channel = &band->channels[j];
17321 /* The Rx BDs contain SNR values in dB for the received frames
17322 * while the supplicant expects noise. So we calculate and
17323 * return the value of noise (dBm)
17324 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17325 */
17326 survey->noise = rssi - snr;
17327 survey->filled = SURVEY_INFO_NOISE_DBM;
17328 filled = 1;
17329 }
17330 }
17331 }
17332
17333 if (filled)
17334 pAdapter->survey_idx = 1;
17335 else
17336 {
17337 pAdapter->survey_idx = 0;
17338 return -ENONET;
17339 }
17340
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017341 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017342 return 0;
17343}
17344
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017345static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17346 struct net_device *dev,
17347 int idx, struct survey_info *survey)
17348{
17349 int ret;
17350
17351 vos_ssr_protect(__func__);
17352 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17353 vos_ssr_unprotect(__func__);
17354
17355 return ret;
17356}
17357
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017358/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017359 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017360 * this is called when cfg80211 driver resume
17361 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17362 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017363int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017364{
17365 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17366 hdd_adapter_t *pAdapter;
17367 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17368 VOS_STATUS status = VOS_STATUS_SUCCESS;
17369
17370 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017371
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017372 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017373 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017374 return 0;
17375 }
17376
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017377 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17378 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017379 spin_lock(&pHddCtx->schedScan_lock);
17380 pHddCtx->isWiphySuspended = FALSE;
17381 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17382 {
17383 spin_unlock(&pHddCtx->schedScan_lock);
17384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17385 "%s: Return resume is not due to PNO indication", __func__);
17386 return 0;
17387 }
17388 // Reset flag to avoid updatating cfg80211 data old results again
17389 pHddCtx->isSchedScanUpdatePending = FALSE;
17390 spin_unlock(&pHddCtx->schedScan_lock);
17391
17392 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17393
17394 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17395 {
17396 pAdapter = pAdapterNode->pAdapter;
17397 if ( (NULL != pAdapter) &&
17398 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17399 {
17400 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017401 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17403 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017404 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017405 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017406 {
17407 /* Acquire wakelock to handle the case where APP's tries to
17408 * suspend immediately after updating the scan results. Whis
17409 * results in app's is in suspended state and not able to
17410 * process the connect request to AP
17411 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017412 hdd_prevent_suspend_timeout(2000,
17413 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017414 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017415 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017416
17417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17418 "%s : cfg80211 scan result database updated", __func__);
17419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017420 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017421 return 0;
17422
17423 }
17424 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17425 pAdapterNode = pNext;
17426 }
17427
17428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17429 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017430 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017431 return 0;
17432}
17433
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017434int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17435{
17436 int ret;
17437
17438 vos_ssr_protect(__func__);
17439 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17440 vos_ssr_unprotect(__func__);
17441
17442 return ret;
17443}
17444
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017445/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017446 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017447 * this is called when cfg80211 driver suspends
17448 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017449int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017450 struct cfg80211_wowlan *wow)
17451{
17452 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017453 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017454
17455 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017456
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017457 ret = wlan_hdd_validate_context(pHddCtx);
17458 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017459 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017460 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017461 }
17462
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017463
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17465 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17466 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017467 pHddCtx->isWiphySuspended = TRUE;
17468
17469 EXIT();
17470
17471 return 0;
17472}
17473
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017474int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17475 struct cfg80211_wowlan *wow)
17476{
17477 int ret;
17478
17479 vos_ssr_protect(__func__);
17480 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17481 vos_ssr_unprotect(__func__);
17482
17483 return ret;
17484}
Jeff Johnson295189b2012-06-20 16:38:30 -070017485/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017486static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017487{
17488 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17489 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17490 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17491 .change_station = wlan_hdd_change_station,
17492#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17493 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17494 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17495 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017496#else
17497 .start_ap = wlan_hdd_cfg80211_start_ap,
17498 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17499 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017500#endif
17501 .change_bss = wlan_hdd_cfg80211_change_bss,
17502 .add_key = wlan_hdd_cfg80211_add_key,
17503 .get_key = wlan_hdd_cfg80211_get_key,
17504 .del_key = wlan_hdd_cfg80211_del_key,
17505 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017506#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017507 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017508#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017509 .scan = wlan_hdd_cfg80211_scan,
17510 .connect = wlan_hdd_cfg80211_connect,
17511 .disconnect = wlan_hdd_cfg80211_disconnect,
17512 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17513 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17514 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17515 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17516 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017517 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17518 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017519 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17521 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17522 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17523 .set_txq_params = wlan_hdd_set_txq_params,
17524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017525 .get_station = wlan_hdd_cfg80211_get_station,
17526 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17527 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017528 .add_station = wlan_hdd_cfg80211_add_station,
17529#ifdef FEATURE_WLAN_LFR
17530 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17531 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17532 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17533#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017534#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17535 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17536#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017537#ifdef FEATURE_WLAN_TDLS
17538 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17539 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17540#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017541#ifdef WLAN_FEATURE_GTK_OFFLOAD
17542 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17543#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017544#ifdef FEATURE_WLAN_SCAN_PNO
17545 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17546 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17547#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017548 .resume = wlan_hdd_cfg80211_resume_wlan,
17549 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017550 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017551#ifdef WLAN_NL80211_TESTMODE
17552 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17553#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017554 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017555};
17556