blob: 9840645e5ac489485a548aedb593b26cc09d765e [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
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305597
5598static const struct
5599nla_policy
5600qca_wlan_vendor_wifi_logger_get_ring_data_policy
5601[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5602 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5603 = {.type = NLA_U32 },
5604};
5605
5606static int
5607 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5608 struct wireless_dev *wdev,
5609 const void *data,
5610 int data_len)
5611{
5612 int ret;
5613 VOS_STATUS status;
5614 uint32_t ring_id;
5615 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5616 struct nlattr *tb
5617 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5618
5619 ENTER();
5620
5621 ret = wlan_hdd_validate_context(hdd_ctx);
5622 if (0 != ret) {
5623 return ret;
5624 }
5625
5626 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5627 data, data_len,
5628 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5629 hddLog(LOGE, FL("Invalid attribute"));
5630 return -EINVAL;
5631 }
5632
5633 /* Parse and fetch ring id */
5634 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5635 hddLog(LOGE, FL("attr ATTR failed"));
5636 return -EINVAL;
5637 }
5638
5639 ring_id = nla_get_u32(
5640 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5641
5642 hddLog(LOG1, FL("Bug report triggered by framework"));
5643
5644 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5645 WLAN_LOG_INDICATOR_FRAMEWORK,
5646 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305647 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305648 );
5649 if (VOS_STATUS_SUCCESS != status) {
5650 hddLog(LOGE, FL("Failed to trigger bug report"));
5651
5652 return -EINVAL;
5653 }
5654
5655 return 0;
5656
5657
5658}
5659
5660
5661static int
5662 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5663 struct wireless_dev *wdev,
5664 const void *data,
5665 int data_len)
5666{
5667 int ret = 0;
5668
5669 vos_ssr_protect(__func__);
5670 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5671 wdev, data, data_len);
5672 vos_ssr_unprotect(__func__);
5673
5674 return ret;
5675
5676}
5677
5678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679static int
5680__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305681 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305682 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305683{
5684 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5685 uint8_t i, feature_sets, max_feature_sets;
5686 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5687 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305688 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5689 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305690
5691 ENTER();
5692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305693 ret = wlan_hdd_validate_context(pHddCtx);
5694 if (0 != ret)
5695 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305696 return ret;
5697 }
5698
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305699 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5700 data, data_len, NULL)) {
5701 hddLog(LOGE, FL("Invalid ATTR"));
5702 return -EINVAL;
5703 }
5704
5705 /* Parse and fetch max feature set */
5706 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5707 hddLog(LOGE, FL("Attr max feature set size failed"));
5708 return -EINVAL;
5709 }
5710 max_feature_sets = nla_get_u32(
5711 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5712 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5713
5714 /* Fill feature combination matrix */
5715 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5717 WIFI_FEATURE_P2P;
5718
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305719 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5720 WIFI_FEATURE_SOFT_AP;
5721
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305722 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5723 WIFI_FEATURE_SOFT_AP;
5724
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5726 WIFI_FEATURE_SOFT_AP |
5727 WIFI_FEATURE_P2P;
5728
5729 /* Add more feature combinations here */
5730
5731 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5732 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5733 hddLog(LOG1, "Feature set matrix");
5734 for (i = 0; i < feature_sets; i++)
5735 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5736
5737 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5738 sizeof(u32) * feature_sets +
5739 NLMSG_HDRLEN);
5740
5741 if (reply_skb) {
5742 if (nla_put_u32(reply_skb,
5743 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5744 feature_sets) ||
5745 nla_put(reply_skb,
5746 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5747 sizeof(u32) * feature_sets, feature_set_matrix)) {
5748 hddLog(LOGE, FL("nla put fail"));
5749 kfree_skb(reply_skb);
5750 return -EINVAL;
5751 }
5752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305753 ret = cfg80211_vendor_cmd_reply(reply_skb);
5754 EXIT();
5755 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305756 }
5757 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5758 return -ENOMEM;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760}
5761
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762static int
5763wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5764 struct wireless_dev *wdev,
5765 const void *data, int data_len)
5766{
5767 int ret = 0;
5768
5769 vos_ssr_protect(__func__);
5770 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5771 data_len);
5772 vos_ssr_unprotect(__func__);
5773
5774 return ret;
5775}
5776
c_manjeecfd1efb2015-09-25 19:32:34 +05305777
5778static int
5779__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5780 struct wireless_dev *wdev,
5781 const void *data, int data_len)
5782{
5783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5784 int ret;
5785 ENTER();
5786
5787 ret = wlan_hdd_validate_context(pHddCtx);
5788 if (0 != ret)
5789 {
5790 return ret;
5791 }
5792
5793 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5794 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5795 {
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5797 return -EINVAL;
5798 }
5799 /*call common API for FW mem dump req*/
5800 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5801
5802 EXIT();
5803 return ret;
5804}
5805
5806/**
5807 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5808 * @wiphy: pointer to wireless wiphy structure.
5809 * @wdev: pointer to wireless_dev structure.
5810 * @data: Pointer to the NL data.
5811 * @data_len:Length of @data
5812 *
5813 * This is called when wlan driver needs to get the firmware memory dump
5814 * via vendor specific command.
5815 *
5816 * Return: 0 on success, error number otherwise.
5817 */
5818
5819static int
5820wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5821 struct wireless_dev *wdev,
5822 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305823{
5824 int ret = 0;
5825 vos_ssr_protect(__func__);
5826 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5827 data_len);
5828 vos_ssr_unprotect(__func__);
5829 return ret;
5830}
c_manjeecfd1efb2015-09-25 19:32:34 +05305831
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832static const struct
5833nla_policy
5834qca_wlan_vendor_wifi_logger_start_policy
5835[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5836 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5837 = {.type = NLA_U32 },
5838 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5839 = {.type = NLA_U32 },
5840 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5841 = {.type = NLA_U32 },
5842};
5843
5844/**
5845 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5846 * or disable the collection of packet statistics from the firmware
5847 * @wiphy: WIPHY structure pointer
5848 * @wdev: Wireless device structure pointer
5849 * @data: Pointer to the data received
5850 * @data_len: Length of the data received
5851 *
5852 * This function is used to enable or disable the collection of packet
5853 * statistics from the firmware
5854 *
5855 * Return: 0 on success and errno on failure
5856 */
5857static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5858 struct wireless_dev *wdev,
5859 const void *data,
5860 int data_len)
5861{
5862 eHalStatus status;
5863 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5864 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5865 tAniWifiStartLog start_log;
5866
5867 status = wlan_hdd_validate_context(hdd_ctx);
5868 if (0 != status) {
5869 return -EINVAL;
5870 }
5871
5872 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5873 data, data_len,
5874 qca_wlan_vendor_wifi_logger_start_policy)) {
5875 hddLog(LOGE, FL("Invalid attribute"));
5876 return -EINVAL;
5877 }
5878
5879 /* Parse and fetch ring id */
5880 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5881 hddLog(LOGE, FL("attr ATTR failed"));
5882 return -EINVAL;
5883 }
5884 start_log.ringId = nla_get_u32(
5885 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5886 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5887
5888 /* Parse and fetch verbose level */
5889 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5890 hddLog(LOGE, FL("attr verbose_level failed"));
5891 return -EINVAL;
5892 }
5893 start_log.verboseLevel = nla_get_u32(
5894 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5895 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5896
5897 /* Parse and fetch flag */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5899 hddLog(LOGE, FL("attr flag failed"));
5900 return -EINVAL;
5901 }
5902 start_log.flag = nla_get_u32(
5903 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5904 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5905
5906 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305907 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5908 !vos_isPktStatsEnabled()))
5909
Sushant Kaushik8e644982015-09-23 12:18:54 +05305910 {
5911 hddLog(LOGE, FL("per pkt stats not enabled"));
5912 return -EINVAL;
5913 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305914
Sushant Kaushik33200572015-08-05 16:46:20 +05305915 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916 return 0;
5917}
5918
5919/**
5920 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5921 * or disable the collection of packet statistics from the firmware
5922 * @wiphy: WIPHY structure pointer
5923 * @wdev: Wireless device structure pointer
5924 * @data: Pointer to the data received
5925 * @data_len: Length of the data received
5926 *
5927 * This function is used to enable or disable the collection of packet
5928 * statistics from the firmware
5929 *
5930 * Return: 0 on success and errno on failure
5931 */
5932static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5933 struct wireless_dev *wdev,
5934 const void *data,
5935 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305936{
5937 int ret = 0;
5938
5939 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305940
5941 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5942 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305943 vos_ssr_unprotect(__func__);
5944
5945 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305946}
5947
5948
Agarwal Ashish738843c2014-09-25 12:27:56 +05305949static const struct nla_policy
5950wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5951 +1] =
5952{
5953 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5954};
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305957 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305958 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305959 int data_len)
5960{
5961 struct net_device *dev = wdev->netdev;
5962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5963 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5964 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5965 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5966 eHalStatus status;
5967 u32 dfsFlag = 0;
5968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305969 ENTER();
5970
Agarwal Ashish738843c2014-09-25 12:27:56 +05305971 status = wlan_hdd_validate_context(pHddCtx);
5972 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305973 return -EINVAL;
5974 }
5975 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5976 data, data_len,
5977 wlan_hdd_set_no_dfs_flag_config_policy)) {
5978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5979 return -EINVAL;
5980 }
5981
5982 /* Parse and fetch required bandwidth kbps */
5983 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5985 return -EINVAL;
5986 }
5987
5988 dfsFlag = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5990 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5991 dfsFlag);
5992
5993 pHddCtx->disable_dfs_flag = dfsFlag;
5994
5995 sme_disable_dfs_channel(hHal, dfsFlag);
5996 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305997
5998 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305999 return 0;
6000}
Atul Mittal115287b2014-07-08 13:26:33 +05306001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306002static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6003 struct wireless_dev *wdev,
6004 const void *data,
6005 int data_len)
6006{
6007 int ret = 0;
6008
6009 vos_ssr_protect(__func__);
6010 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6011 vos_ssr_unprotect(__func__);
6012
6013 return ret;
6014
6015}
6016
Mukul Sharma2a271632014-10-13 14:59:01 +05306017const struct
6018nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6019{
6020 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6021 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6022};
6023
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306024static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306025 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306026{
6027
6028 u8 bssid[6] = {0};
6029 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6030 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6031 eHalStatus status = eHAL_STATUS_SUCCESS;
6032 v_U32_t isFwrRoamEnabled = FALSE;
6033 int ret;
6034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306035 ENTER();
6036
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306037 ret = wlan_hdd_validate_context(pHddCtx);
6038 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306040 }
6041
6042 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6043 data, data_len,
6044 qca_wlan_vendor_attr);
6045 if (ret){
6046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6047 return -EINVAL;
6048 }
6049
6050 /* Parse and fetch Enable flag */
6051 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6053 return -EINVAL;
6054 }
6055
6056 isFwrRoamEnabled = nla_get_u32(
6057 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6058
6059 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6060
6061 /* Parse and fetch bssid */
6062 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6064 return -EINVAL;
6065 }
6066
6067 memcpy(bssid, nla_data(
6068 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6069 sizeof(bssid));
6070 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6071
6072 //Update roaming
6073 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306074 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306075 return status;
6076}
6077
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306078static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6079 struct wireless_dev *wdev, const void *data, int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088}
6089
Sushant Kaushik847890c2015-09-28 16:05:17 +05306090static const struct
6091nla_policy
6092qca_wlan_vendor_get_wifi_info_policy[
6093 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6094 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6095 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6096};
6097
6098
6099/**
6100 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6101 * @wiphy: pointer to wireless wiphy structure.
6102 * @wdev: pointer to wireless_dev structure.
6103 * @data: Pointer to the data to be passed via vendor interface
6104 * @data_len:Length of the data to be passed
6105 *
6106 * This is called when wlan driver needs to send wifi driver related info
6107 * (driver/fw version) to the user space application upon request.
6108 *
6109 * Return: Return the Success or Failure code.
6110 */
6111static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6112 struct wireless_dev *wdev,
6113 const void *data, int data_len)
6114{
6115 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6116 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6117 tSirVersionString version;
6118 uint32 version_len;
6119 uint8 attr;
6120 int status;
6121 struct sk_buff *reply_skb = NULL;
6122
6123 if (VOS_FTM_MODE == hdd_get_conparam()) {
6124 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6125 return -EINVAL;
6126 }
6127
6128 status = wlan_hdd_validate_context(hdd_ctx);
6129 if (0 != status) {
6130 hddLog(LOGE, FL("HDD context is not valid"));
6131 return -EINVAL;
6132 }
6133
6134 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6135 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6136 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6137 return -EINVAL;
6138 }
6139
6140 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6141 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6142 QWLAN_VERSIONSTR);
6143 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6144 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6145 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6146 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6147 hdd_ctx->fw_Version);
6148 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6149 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6150 } else {
6151 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6152 return -EINVAL;
6153 }
6154
6155 version_len = strlen(version);
6156 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6157 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6158 if (!reply_skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -ENOMEM;
6161 }
6162
6163 if (nla_put(reply_skb, attr, version_len, version)) {
6164 hddLog(LOGE, FL("nla put fail"));
6165 kfree_skb(reply_skb);
6166 return -EINVAL;
6167 }
6168
6169 return cfg80211_vendor_cmd_reply(reply_skb);
6170}
6171
6172/**
6173 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6174 * @wiphy: pointer to wireless wiphy structure.
6175 * @wdev: pointer to wireless_dev structure.
6176 * @data: Pointer to the data to be passed via vendor interface
6177 * @data_len:Length of the data to be passed
6178 * @data_len: Length of the data received
6179 *
6180 * This function is used to enable or disable the collection of packet
6181 * statistics from the firmware
6182 *
6183 * Return: 0 on success and errno on failure
6184 */
6185
6186static int
6187wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6188 struct wireless_dev *wdev,
6189 const void *data, int data_len)
6190
6191
6192{
6193 int ret = 0;
6194
6195 vos_ssr_protect(__func__);
6196 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6197 wdev, data, data_len);
6198 vos_ssr_unprotect(__func__);
6199
6200 return ret;
6201}
6202
6203
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306204/*
6205 * define short names for the global vendor params
6206 * used by __wlan_hdd_cfg80211_monitor_rssi()
6207 */
6208#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6209#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6210#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6211#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6212#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6213
6214/**---------------------------------------------------------------------------
6215
6216 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6217 monitor start is completed successfully.
6218
6219 \return - None
6220
6221 --------------------------------------------------------------------------*/
6222void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6223{
6224 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6225
6226 if (NULL == pHddCtx)
6227 {
6228 hddLog(VOS_TRACE_LEVEL_ERROR,
6229 "%s: HDD context is NULL",__func__);
6230 return;
6231 }
6232
6233 if (VOS_STATUS_SUCCESS == status)
6234 {
6235 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6236 }
6237 else
6238 {
6239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6240 }
6241
6242 return;
6243}
6244
6245/**---------------------------------------------------------------------------
6246
6247 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6248 stop is completed successfully.
6249
6250 \return - None
6251
6252 --------------------------------------------------------------------------*/
6253void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6254{
6255 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6256
6257 if (NULL == pHddCtx)
6258 {
6259 hddLog(VOS_TRACE_LEVEL_ERROR,
6260 "%s: HDD context is NULL",__func__);
6261 return;
6262 }
6263
6264 if (VOS_STATUS_SUCCESS == status)
6265 {
6266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6267 }
6268 else
6269 {
6270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6271 }
6272
6273 return;
6274}
6275
6276/**
6277 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6278 * @wiphy: Pointer to wireless phy
6279 * @wdev: Pointer to wireless device
6280 * @data: Pointer to data
6281 * @data_len: Data length
6282 *
6283 * Return: 0 on success, negative errno on failure
6284 */
6285
6286static int
6287__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6288 struct wireless_dev *wdev,
6289 const void *data,
6290 int data_len)
6291{
6292 struct net_device *dev = wdev->netdev;
6293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6294 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6295 hdd_station_ctx_t *pHddStaCtx;
6296 struct nlattr *tb[PARAM_MAX + 1];
6297 tpSirRssiMonitorReq pReq;
6298 eHalStatus status;
6299 int ret;
6300 uint32_t control;
6301 static const struct nla_policy policy[PARAM_MAX + 1] = {
6302 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6303 [PARAM_CONTROL] = { .type = NLA_U32 },
6304 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6305 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6306 };
6307
6308 ENTER();
6309
6310 ret = wlan_hdd_validate_context(hdd_ctx);
6311 if (0 != ret) {
6312 return -EINVAL;
6313 }
6314
6315 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6316 hddLog(LOGE, FL("Not in Connected state!"));
6317 return -ENOTSUPP;
6318 }
6319
6320 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6321 hddLog(LOGE, FL("Invalid ATTR"));
6322 return -EINVAL;
6323 }
6324
6325 if (!tb[PARAM_REQUEST_ID]) {
6326 hddLog(LOGE, FL("attr request id failed"));
6327 return -EINVAL;
6328 }
6329
6330 if (!tb[PARAM_CONTROL]) {
6331 hddLog(LOGE, FL("attr control failed"));
6332 return -EINVAL;
6333 }
6334
6335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6336
6337 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6338 if(NULL == pReq)
6339 {
6340 hddLog(LOGE,
6341 FL("vos_mem_alloc failed "));
6342 return eHAL_STATUS_FAILED_ALLOC;
6343 }
6344 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6345
6346 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6347 pReq->sessionId = pAdapter->sessionId;
6348 pReq->rssiMonitorCbContext = hdd_ctx;
6349 control = nla_get_u32(tb[PARAM_CONTROL]);
6350 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6351
6352 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6353 pReq->requestId, pReq->sessionId, control);
6354
6355 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6356 if (!tb[PARAM_MIN_RSSI]) {
6357 hddLog(LOGE, FL("attr min rssi failed"));
6358 return -EINVAL;
6359 }
6360
6361 if (!tb[PARAM_MAX_RSSI]) {
6362 hddLog(LOGE, FL("attr max rssi failed"));
6363 return -EINVAL;
6364 }
6365
6366 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6367 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6368 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6369
6370 if (!(pReq->minRssi < pReq->maxRssi)) {
6371 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6372 pReq->minRssi, pReq->maxRssi);
6373 return -EINVAL;
6374 }
6375 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6376 pReq->minRssi, pReq->maxRssi);
6377 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6378
6379 }
6380 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6381 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6382 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6383 }
6384 else {
6385 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6386 return -EINVAL;
6387 }
6388
6389 if (!HAL_STATUS_SUCCESS(status)) {
6390 hddLog(LOGE,
6391 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6392 return -EINVAL;
6393 }
6394
6395 return 0;
6396}
6397
6398/*
6399 * done with short names for the global vendor params
6400 * used by __wlan_hdd_cfg80211_monitor_rssi()
6401 */
6402#undef PARAM_MAX
6403#undef PARAM_CONTROL
6404#undef PARAM_REQUEST_ID
6405#undef PARAM_MAX_RSSI
6406#undef PARAM_MIN_RSSI
6407
6408/**
6409 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6410 * @wiphy: wiphy structure pointer
6411 * @wdev: Wireless device structure pointer
6412 * @data: Pointer to the data received
6413 * @data_len: Length of @data
6414 *
6415 * Return: 0 on success; errno on failure
6416 */
6417static int
6418wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6419 const void *data, int data_len)
6420{
6421 int ret;
6422
6423 vos_ssr_protect(__func__);
6424 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6425 vos_ssr_unprotect(__func__);
6426
6427 return ret;
6428}
6429
6430/**
6431 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6432 * @hddctx: HDD context
6433 * @data: rssi breached event data
6434 *
6435 * This function reads the rssi breached event %data and fill in the skb with
6436 * NL attributes and send up the NL event.
6437 * This callback execute in atomic context and must not invoke any
6438 * blocking calls.
6439 *
6440 * Return: none
6441 */
6442void hdd_rssi_threshold_breached_cb(void *hddctx,
6443 struct rssi_breach_event *data)
6444{
6445 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6446 int status;
6447 struct sk_buff *skb;
6448
6449 ENTER();
6450 status = wlan_hdd_validate_context(pHddCtx);
6451
6452 if (0 != status) {
6453 return;
6454 }
6455
6456 if (!data) {
6457 hddLog(LOGE, FL("data is null"));
6458 return;
6459 }
6460
6461 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6463 NULL,
6464#endif
6465 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6466 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6467 GFP_KERNEL);
6468
6469 if (!skb) {
6470 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6471 return;
6472 }
6473
6474 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6475 data->request_id, data->curr_rssi);
6476 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6477 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6478
6479 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6480 data->request_id) ||
6481 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6482 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6483 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6484 data->curr_rssi)) {
6485 hddLog(LOGE, FL("nla put fail"));
6486 goto fail;
6487 }
6488
6489 cfg80211_vendor_event(skb, GFP_KERNEL);
6490 return;
6491
6492fail:
6493 kfree_skb(skb);
6494 return;
6495}
6496
6497
6498
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306499/**
6500 * __wlan_hdd_cfg80211_setband() - set band
6501 * @wiphy: Pointer to wireless phy
6502 * @wdev: Pointer to wireless device
6503 * @data: Pointer to data
6504 * @data_len: Data length
6505 *
6506 * Return: 0 on success, negative errno on failure
6507 */
6508static int
6509__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6510 struct wireless_dev *wdev,
6511 const void *data,
6512 int data_len)
6513{
6514 struct net_device *dev = wdev->netdev;
6515 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6516 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6517 int ret;
6518 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6519 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6520
6521 ENTER();
6522
6523 ret = wlan_hdd_validate_context(hdd_ctx);
6524 if (0 != ret) {
6525 hddLog(LOGE, FL("HDD context is not valid"));
6526 return ret;
6527 }
6528
6529 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6530 policy)) {
6531 hddLog(LOGE, FL("Invalid ATTR"));
6532 return -EINVAL;
6533 }
6534
6535 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6536 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6537 return -EINVAL;
6538 }
6539
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306540 hdd_ctx->isSetBandByNL = TRUE;
6541 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306542 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306543 hdd_ctx->isSetBandByNL = FALSE;
6544
6545 EXIT();
6546 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306547}
6548
6549/**
6550 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6551 * @wiphy: wiphy structure pointer
6552 * @wdev: Wireless device structure pointer
6553 * @data: Pointer to the data received
6554 * @data_len: Length of @data
6555 *
6556 * Return: 0 on success; errno on failure
6557 */
6558static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6559 struct wireless_dev *wdev,
6560 const void *data,
6561 int data_len)
6562{
6563 int ret = 0;
6564
6565 vos_ssr_protect(__func__);
6566 ret = __wlan_hdd_cfg80211_setband(wiphy,
6567 wdev, data, data_len);
6568 vos_ssr_unprotect(__func__);
6569
6570 return ret;
6571}
6572
Sunil Duttc69bccb2014-05-26 21:30:20 +05306573const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6574{
Mukul Sharma2a271632014-10-13 14:59:01 +05306575 {
6576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6579 WIPHY_VENDOR_CMD_NEED_NETDEV |
6580 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306581 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306582 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306583
6584 {
6585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6588 WIPHY_VENDOR_CMD_NEED_NETDEV |
6589 WIPHY_VENDOR_CMD_NEED_RUNNING,
6590 .doit = wlan_hdd_cfg80211_nan_request
6591 },
6592
Sunil Duttc69bccb2014-05-26 21:30:20 +05306593#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6594 {
6595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6598 WIPHY_VENDOR_CMD_NEED_NETDEV |
6599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306600 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306601 },
6602
6603 {
6604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6607 WIPHY_VENDOR_CMD_NEED_NETDEV |
6608 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306609 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306610 },
6611
6612 {
6613 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6614 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6615 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6616 WIPHY_VENDOR_CMD_NEED_NETDEV |
6617 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306618 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306619 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306620#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306621#ifdef WLAN_FEATURE_EXTSCAN
6622 {
6623 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6624 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6625 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6626 WIPHY_VENDOR_CMD_NEED_NETDEV |
6627 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306628 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306629 },
6630 {
6631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6634 WIPHY_VENDOR_CMD_NEED_NETDEV |
6635 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306636 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306637 },
6638 {
6639 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6640 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6641 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6642 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306643 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306644 },
6645 {
6646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6649 WIPHY_VENDOR_CMD_NEED_NETDEV |
6650 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306651 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306652 },
6653 {
6654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6657 WIPHY_VENDOR_CMD_NEED_NETDEV |
6658 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306659 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306660 },
6661 {
6662 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6663 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6664 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6665 WIPHY_VENDOR_CMD_NEED_NETDEV |
6666 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306667 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306668 },
6669 {
6670 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6671 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6672 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6673 WIPHY_VENDOR_CMD_NEED_NETDEV |
6674 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306675 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306676 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306677 {
6678 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6679 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6680 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6681 WIPHY_VENDOR_CMD_NEED_NETDEV |
6682 WIPHY_VENDOR_CMD_NEED_RUNNING,
6683 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6684 },
6685 {
6686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6689 WIPHY_VENDOR_CMD_NEED_NETDEV |
6690 WIPHY_VENDOR_CMD_NEED_RUNNING,
6691 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6692 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306693#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306694/*EXT TDLS*/
6695 {
6696 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6697 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6698 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6699 WIPHY_VENDOR_CMD_NEED_NETDEV |
6700 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306701 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306702 },
6703 {
6704 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6705 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6706 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6707 WIPHY_VENDOR_CMD_NEED_NETDEV |
6708 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306709 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306710 },
6711 {
6712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6715 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306716 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306717 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306718 {
6719 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6720 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6721 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6722 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306723 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306724 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306725 {
6726 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6727 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6728 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6729 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306730 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306731 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306732 {
6733 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6734 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6735 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6736 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306737 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306738 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306739 {
6740 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6741 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6742 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6743 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306744 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306745 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306746 {
6747 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306748 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6749 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6750 WIPHY_VENDOR_CMD_NEED_NETDEV |
6751 WIPHY_VENDOR_CMD_NEED_RUNNING,
6752 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6753 },
6754 {
6755 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306756 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6757 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6758 WIPHY_VENDOR_CMD_NEED_NETDEV |
6759 WIPHY_VENDOR_CMD_NEED_RUNNING,
6760 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05306761 },
6762 {
6763 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6764 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
6765 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6766 WIPHY_VENDOR_CMD_NEED_NETDEV,
6767 .doit = wlan_hdd_cfg80211_wifi_logger_start
6768 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05306769 {
6770 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6771 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6772 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6773 WIPHY_VENDOR_CMD_NEED_NETDEV|
6774 WIPHY_VENDOR_CMD_NEED_RUNNING,
6775 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306776 },
6777 {
6778 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6779 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
6780 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6781 WIPHY_VENDOR_CMD_NEED_NETDEV |
6782 WIPHY_VENDOR_CMD_NEED_RUNNING,
6783 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306784 },
6785 {
6786 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6787 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
6788 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6789 WIPHY_VENDOR_CMD_NEED_NETDEV |
6790 WIPHY_VENDOR_CMD_NEED_RUNNING,
6791 .doit = wlan_hdd_cfg80211_monitor_rssi
Sushant Kaushik847890c2015-09-28 16:05:17 +05306792 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306793};
6794
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006795/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306796static const
6797struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006798{
6799#ifdef FEATURE_WLAN_CH_AVOID
6800 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306801 .vendor_id = QCA_NL80211_VENDOR_ID,
6802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006803 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306804#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6805#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6806 {
6807 /* Index = 1*/
6808 .vendor_id = QCA_NL80211_VENDOR_ID,
6809 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6810 },
6811 {
6812 /* Index = 2*/
6813 .vendor_id = QCA_NL80211_VENDOR_ID,
6814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6815 },
6816 {
6817 /* Index = 3*/
6818 .vendor_id = QCA_NL80211_VENDOR_ID,
6819 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6820 },
6821 {
6822 /* Index = 4*/
6823 .vendor_id = QCA_NL80211_VENDOR_ID,
6824 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6825 },
6826 {
6827 /* Index = 5*/
6828 .vendor_id = QCA_NL80211_VENDOR_ID,
6829 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6830 },
6831 {
6832 /* Index = 6*/
6833 .vendor_id = QCA_NL80211_VENDOR_ID,
6834 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6835 },
6836#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306837#ifdef WLAN_FEATURE_EXTSCAN
6838 {
6839 .vendor_id = QCA_NL80211_VENDOR_ID,
6840 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6841 },
6842 {
6843 .vendor_id = QCA_NL80211_VENDOR_ID,
6844 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6845 },
6846 {
6847 .vendor_id = QCA_NL80211_VENDOR_ID,
6848 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6849 },
6850 {
6851 .vendor_id = QCA_NL80211_VENDOR_ID,
6852 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6853 },
6854 {
6855 .vendor_id = QCA_NL80211_VENDOR_ID,
6856 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6857 },
6858 {
6859 .vendor_id = QCA_NL80211_VENDOR_ID,
6860 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6861 },
6862 {
6863 .vendor_id = QCA_NL80211_VENDOR_ID,
6864 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6865 },
6866 {
6867 .vendor_id = QCA_NL80211_VENDOR_ID,
6868 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6869 },
6870 {
6871 .vendor_id = QCA_NL80211_VENDOR_ID,
6872 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6873 },
6874 {
6875 .vendor_id = QCA_NL80211_VENDOR_ID,
6876 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6877 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306878 {
6879 .vendor_id = QCA_NL80211_VENDOR_ID,
6880 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6881 },
6882 {
6883 .vendor_id = QCA_NL80211_VENDOR_ID,
6884 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6885 },
6886 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6887 .vendor_id = QCA_NL80211_VENDOR_ID,
6888 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6889 },
6890 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6891 .vendor_id = QCA_NL80211_VENDOR_ID,
6892 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6893 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306894#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306895/*EXT TDLS*/
6896 {
6897 .vendor_id = QCA_NL80211_VENDOR_ID,
6898 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6899 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306900 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6901 .vendor_id = QCA_NL80211_VENDOR_ID,
6902 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6903 },
6904
Srinivas Dasari030bad32015-02-18 23:23:54 +05306905
6906 {
6907 .vendor_id = QCA_NL80211_VENDOR_ID,
6908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6909 },
6910
Sushant Kaushik084f6592015-09-10 13:11:56 +05306911 {
6912 .vendor_id = QCA_NL80211_VENDOR_ID,
6913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306914 },
6915 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
6916 .vendor_id = QCA_NL80211_VENDOR_ID,
6917 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
6918 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05306919
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006920};
6921
Jeff Johnson295189b2012-06-20 16:38:30 -07006922/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306923 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 * This function is called by hdd_wlan_startup()
6925 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306926 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306928struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006929{
6930 struct wiphy *wiphy;
6931 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932 /*
6933 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 */
6935 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6936
6937 if (!wiphy)
6938 {
6939 /* Print error and jump into err label and free the memory */
6940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6941 return NULL;
6942 }
6943
Sunil Duttc69bccb2014-05-26 21:30:20 +05306944
Jeff Johnson295189b2012-06-20 16:38:30 -07006945 return wiphy;
6946}
6947
6948/*
6949 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 * private ioctl to change the band value
6952 */
6953int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6954{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306955 int i, j;
6956 eNVChannelEnabledType channelEnabledState;
6957
Jeff Johnsone7245742012-09-05 17:12:55 -07006958 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306959
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306960 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306962
6963 if (NULL == wiphy->bands[i])
6964 {
6965 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6966 __func__, i);
6967 continue;
6968 }
6969
6970 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6971 {
6972 struct ieee80211_supported_band *band = wiphy->bands[i];
6973
6974 channelEnabledState = vos_nv_getChannelEnabledState(
6975 band->channels[j].hw_value);
6976
6977 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6978 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306979 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306980 continue;
6981 }
6982 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6983 {
6984 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6985 continue;
6986 }
6987
6988 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6989 NV_CHANNEL_INVALID == channelEnabledState)
6990 {
6991 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6992 }
6993 else if (NV_CHANNEL_DFS == channelEnabledState)
6994 {
6995 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6996 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6997 }
6998 else
6999 {
7000 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7001 |IEEE80211_CHAN_RADAR);
7002 }
7003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 }
7005 return 0;
7006}
7007/*
7008 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307009 * This function is called by hdd_wlan_startup()
7010 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 * This function is used to initialize and register wiphy structure.
7012 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307013int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 struct wiphy *wiphy,
7015 hdd_config_t *pCfg
7016 )
7017{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307018 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307019 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7020
Jeff Johnsone7245742012-09-05 17:12:55 -07007021 ENTER();
7022
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 /* Now bind the underlying wlan device with wiphy */
7024 set_wiphy_dev(wiphy, dev);
7025
7026 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007027
Kiet Lam6c583332013-10-14 05:37:09 +05307028#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007029 /* the flag for the other case would be initialzed in
7030 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007031 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307032#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007033
Amar Singhalfddc28c2013-09-05 13:03:40 -07007034 /* This will disable updating of NL channels from passive to
7035 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7037 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7038#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007039 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307040#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007041
Amar Singhala49cbc52013-10-08 18:37:44 -07007042
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007044 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7045 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7046 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007047 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7049 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7050#else
7051 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7052#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007053#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007054
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007055#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007056 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007057#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007058 || pCfg->isFastRoamIniFeatureEnabled
7059#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007060#ifdef FEATURE_WLAN_ESE
7061 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007062#endif
7063 )
7064 {
7065 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7066 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007067#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007068#ifdef FEATURE_WLAN_TDLS
7069 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7070 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7071#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307072#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307073 if (pCfg->configPNOScanSupport)
7074 {
7075 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7076 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7077 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7078 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7079 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307080#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007081
Abhishek Singh10d85972015-04-17 10:27:23 +05307082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7083 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7084#endif
7085
Amar Singhalfddc28c2013-09-05 13:03:40 -07007086#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007087 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7088 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007089 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007090 driver need to determine what to do with both
7091 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007092
7093 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007094#else
7095 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007096#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007097
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307098 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7099
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307100 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007101
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307102 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7103
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307105 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7106 | BIT(NL80211_IFTYPE_ADHOC)
7107 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7108 | BIT(NL80211_IFTYPE_P2P_GO)
7109 | BIT(NL80211_IFTYPE_AP);
7110
7111 if (VOS_MONITOR_MODE == hdd_get_conparam())
7112 {
7113 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007115
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307116 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007117 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7119 if( pCfg->enableMCC )
7120 {
7121 /* Currently, supports up to two channels */
7122 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007123
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307124 if( !pCfg->allowMCCGODiffBI )
7125 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007126
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307127 }
7128 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7129 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007130#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307131 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007132
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 /* Before registering we need to update the ht capabilitied based
7134 * on ini values*/
7135 if( !pCfg->ShortGI20MhzEnable )
7136 {
7137 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7138 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7139 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7140 }
7141
7142 if( !pCfg->ShortGI40MhzEnable )
7143 {
7144 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7145 }
7146
7147 if( !pCfg->nChannelBondingMode5GHz )
7148 {
7149 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7150 }
7151
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307152 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307153 if (true == hdd_is_5g_supported(pHddCtx))
7154 {
7155 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
7156 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307157
7158 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
7159 {
7160
7161 if (NULL == wiphy->bands[i])
7162 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05307163 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307164 __func__, i);
7165 continue;
7166 }
7167
7168 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7169 {
7170 struct ieee80211_supported_band *band = wiphy->bands[i];
7171
7172 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
7173 {
7174 // Enable social channels for P2P
7175 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
7176 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7177 else
7178 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7179 continue;
7180 }
7181 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
7182 {
7183 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7184 continue;
7185 }
7186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 }
7188 /*Initialise the supported cipher suite details*/
7189 wiphy->cipher_suites = hdd_cipher_suites;
7190 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
7191
7192 /*signal strength in mBm (100*dBm) */
7193 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7194
7195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05307196 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07007197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007198
Sunil Duttc69bccb2014-05-26 21:30:20 +05307199 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
7200 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007201 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
7202 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
7203
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307204 EXIT();
7205 return 0;
7206}
7207
7208/* In this function we are registering wiphy. */
7209int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
7210{
7211 ENTER();
7212 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 if (0 > wiphy_register(wiphy))
7214 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307215 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
7217 return -EIO;
7218 }
7219
7220 EXIT();
7221 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307222}
Jeff Johnson295189b2012-06-20 16:38:30 -07007223
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307224/* In this function we are updating channel list when,
7225 regulatory domain is FCC and country code is US.
7226 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
7227 As per FCC smart phone is not a indoor device.
7228 GO should not opeate on indoor channels */
7229void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
7230{
7231 int j;
7232 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7233 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
7234 //Default counrtycode from NV at the time of wiphy initialization.
7235 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
7236 &defaultCountryCode[0]))
7237 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007238 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307239 }
7240 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
7241 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307242 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
7243 {
7244 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
7245 return;
7246 }
7247 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
7248 {
7249 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
7250 // Mark UNII -1 band channel as passive
7251 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
7252 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
7253 }
7254 }
7255}
7256
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307257/* This function registers for all frame which supplicant is interested in */
7258void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007259{
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7261 /* Register for all P2P action, public action etc frames */
7262 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
7263
Jeff Johnsone7245742012-09-05 17:12:55 -07007264 ENTER();
7265
Jeff Johnson295189b2012-06-20 16:38:30 -07007266 /* Right now we are registering these frame when driver is getting
7267 initialized. Once we will move to 2.6.37 kernel, in which we have
7268 frame register ops, we will move this code as a part of that */
7269 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307270 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
7272
7273 /* GAS Initial Response */
7274 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7275 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307276
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 /* GAS Comeback Request */
7278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7279 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
7280
7281 /* GAS Comeback Response */
7282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7283 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
7284
7285 /* P2P Public Action */
7286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307287 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 P2P_PUBLIC_ACTION_FRAME_SIZE );
7289
7290 /* P2P Action */
7291 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7292 (v_U8_t*)P2P_ACTION_FRAME,
7293 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07007294
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05307295 /* WNM BSS Transition Request frame */
7296 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7297 (v_U8_t*)WNM_BSS_ACTION_FRAME,
7298 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07007299
7300 /* WNM-Notification */
7301 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7302 (v_U8_t*)WNM_NOTIFICATION_FRAME,
7303 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007304}
7305
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307306void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007307{
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7309 /* Register for all P2P action, public action etc frames */
7310 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
7311
Jeff Johnsone7245742012-09-05 17:12:55 -07007312 ENTER();
7313
Jeff Johnson295189b2012-06-20 16:38:30 -07007314 /* Right now we are registering these frame when driver is getting
7315 initialized. Once we will move to 2.6.37 kernel, in which we have
7316 frame register ops, we will move this code as a part of that */
7317 /* GAS Initial Request */
7318
7319 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7320 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
7321
7322 /* GAS Initial Response */
7323 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7324 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307325
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 /* GAS Comeback Request */
7327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7328 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
7329
7330 /* GAS Comeback Response */
7331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7332 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
7333
7334 /* P2P Public Action */
7335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307336 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 P2P_PUBLIC_ACTION_FRAME_SIZE );
7338
7339 /* P2P Action */
7340 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7341 (v_U8_t*)P2P_ACTION_FRAME,
7342 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07007343 /* WNM-Notification */
7344 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7345 (v_U8_t*)WNM_NOTIFICATION_FRAME,
7346 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007347}
7348
7349#ifdef FEATURE_WLAN_WAPI
7350void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05307351 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07007352{
7353 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7354 tCsrRoamSetKey setKey;
7355 v_BOOL_t isConnected = TRUE;
7356 int status = 0;
7357 v_U32_t roamId= 0xFF;
7358 tANI_U8 *pKeyPtr = NULL;
7359 int n = 0;
7360
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307361 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
7362 __func__, hdd_device_modetoString(pAdapter->device_mode),
7363 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007364
Gopichand Nakkalae7480202013-02-11 15:24:22 +05307365 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 setKey.keyId = key_index; // Store Key ID
7367 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
7368 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
7369 setKey.paeRole = 0 ; // the PAE role
7370 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7371 {
7372 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
7373 }
7374 else
7375 {
7376 isConnected = hdd_connIsConnected(pHddStaCtx);
7377 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
7378 }
7379 setKey.keyLength = key_Len;
7380 pKeyPtr = setKey.Key;
7381 memcpy( pKeyPtr, key, key_Len);
7382
Arif Hussain6d2a3322013-11-17 19:50:10 -08007383 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07007384 __func__, key_Len);
7385 for (n = 0 ; n < key_Len; n++)
7386 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
7387 __func__,n,setKey.Key[n]);
7388
7389 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7390 if ( isConnected )
7391 {
7392 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7393 pAdapter->sessionId, &setKey, &roamId );
7394 }
7395 if ( status != 0 )
7396 {
7397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7398 "[%4d] sme_RoamSetKey returned ERROR status= %d",
7399 __LINE__, status );
7400 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7401 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05307402 /* Need to clear any trace of key value in the memory.
7403 * Thus zero out the memory even though it is local
7404 * variable.
7405 */
7406 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007407}
7408#endif /* FEATURE_WLAN_WAPI*/
7409
7410#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307411int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 beacon_data_t **ppBeacon,
7413 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007414#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307415int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007416 beacon_data_t **ppBeacon,
7417 struct cfg80211_beacon_data *params,
7418 int dtim_period)
7419#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307420{
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 int size;
7422 beacon_data_t *beacon = NULL;
7423 beacon_data_t *old = NULL;
7424 int head_len,tail_len;
7425
Jeff Johnsone7245742012-09-05 17:12:55 -07007426 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307428 {
7429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7430 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307432 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007433
7434 old = pAdapter->sessionCtx.ap.beacon;
7435
7436 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307437 {
7438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7439 FL("session(%d) old and new heads points to NULL"),
7440 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307442 }
7443
7444 if (params->tail && !params->tail_len)
7445 {
7446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7447 FL("tail_len is zero but tail is not NULL"));
7448 return -EINVAL;
7449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007450
Jeff Johnson295189b2012-06-20 16:38:30 -07007451#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
7452 /* Kernel 3.0 is not updating dtim_period for set beacon */
7453 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307454 {
7455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7456 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007459#endif
7460
7461 if(params->head)
7462 head_len = params->head_len;
7463 else
7464 head_len = old->head_len;
7465
7466 if(params->tail || !old)
7467 tail_len = params->tail_len;
7468 else
7469 tail_len = old->tail_len;
7470
7471 size = sizeof(beacon_data_t) + head_len + tail_len;
7472
7473 beacon = kzalloc(size, GFP_KERNEL);
7474
7475 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307476 {
7477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7478 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007481
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007482#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 if(params->dtim_period || !old )
7484 beacon->dtim_period = params->dtim_period;
7485 else
7486 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007487#else
7488 if(dtim_period || !old )
7489 beacon->dtim_period = dtim_period;
7490 else
7491 beacon->dtim_period = old->dtim_period;
7492#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
7495 beacon->tail = beacon->head + head_len;
7496 beacon->head_len = head_len;
7497 beacon->tail_len = tail_len;
7498
7499 if(params->head) {
7500 memcpy (beacon->head,params->head,beacon->head_len);
7501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 if(old)
7504 memcpy (beacon->head,old->head,beacon->head_len);
7505 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307506
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 if(params->tail) {
7508 memcpy (beacon->tail,params->tail,beacon->tail_len);
7509 }
7510 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307511 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07007512 memcpy (beacon->tail,old->tail,beacon->tail_len);
7513 }
7514
7515 *ppBeacon = beacon;
7516
7517 kfree(old);
7518
7519 return 0;
7520
7521}
Jeff Johnson295189b2012-06-20 16:38:30 -07007522
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307523v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
7524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7525 const v_U8_t *pIes,
7526#else
7527 v_U8_t *pIes,
7528#endif
7529 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007530{
7531 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307532 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007533 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307534
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307536 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 elem_id = ptr[0];
7538 elem_len = ptr[1];
7539 left -= 2;
7540 if(elem_len > left)
7541 {
7542 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007543 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 eid,elem_len,left);
7545 return NULL;
7546 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307547 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 {
7549 return ptr;
7550 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307551
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 left -= elem_len;
7553 ptr += (elem_len + 2);
7554 }
7555 return NULL;
7556}
7557
Jeff Johnson295189b2012-06-20 16:38:30 -07007558/* Check if rate is 11g rate or not */
7559static int wlan_hdd_rate_is_11g(u8 rate)
7560{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007561 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 u8 i;
7563 for (i = 0; i < 8; i++)
7564 {
7565 if(rate == gRateArray[i])
7566 return TRUE;
7567 }
7568 return FALSE;
7569}
7570
7571/* Check for 11g rate and set proper 11g only mode */
7572static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7573 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7574{
7575 u8 i, num_rates = pIe[0];
7576
7577 pIe += 1;
7578 for ( i = 0; i < num_rates; i++)
7579 {
7580 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7581 {
7582 /* If rate set have 11g rate than change the mode to 11G */
7583 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7584 if (pIe[i] & BASIC_RATE_MASK)
7585 {
7586 /* If we have 11g rate as basic rate, it means mode
7587 is 11g only mode.
7588 */
7589 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7590 *pCheckRatesfor11g = FALSE;
7591 }
7592 }
7593 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7594 {
7595 *require_ht = TRUE;
7596 }
7597 }
7598 return;
7599}
7600
7601static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7602{
7603 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7604 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7605 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7606 u8 checkRatesfor11g = TRUE;
7607 u8 require_ht = FALSE;
7608 u8 *pIe=NULL;
7609
7610 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7611
7612 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7613 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7614 if (pIe != NULL)
7615 {
7616 pIe += 1;
7617 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7618 &pConfig->SapHw_mode);
7619 }
7620
7621 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7622 WLAN_EID_EXT_SUPP_RATES);
7623 if (pIe != NULL)
7624 {
7625
7626 pIe += 1;
7627 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7628 &pConfig->SapHw_mode);
7629 }
7630
7631 if( pConfig->channel > 14 )
7632 {
7633 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7634 }
7635
7636 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7637 WLAN_EID_HT_CAPABILITY);
7638
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307639 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 {
7641 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7642 if(require_ht)
7643 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7644 }
7645}
7646
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307647static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7648 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7649{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007650 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307651 v_U8_t *pIe = NULL;
7652 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7653
7654 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7655 pBeacon->tail, pBeacon->tail_len);
7656
7657 if (pIe)
7658 {
7659 ielen = pIe[1] + 2;
7660 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7661 {
7662 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7663 }
7664 else
7665 {
7666 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7667 return -EINVAL;
7668 }
7669 *total_ielen += ielen;
7670 }
7671 return 0;
7672}
7673
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007674static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7675 v_U8_t *genie, v_U8_t *total_ielen)
7676{
7677 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7678 int left = pBeacon->tail_len;
7679 v_U8_t *ptr = pBeacon->tail;
7680 v_U8_t elem_id, elem_len;
7681 v_U16_t ielen = 0;
7682
7683 if ( NULL == ptr || 0 == left )
7684 return;
7685
7686 while (left >= 2)
7687 {
7688 elem_id = ptr[0];
7689 elem_len = ptr[1];
7690 left -= 2;
7691 if (elem_len > left)
7692 {
7693 hddLog( VOS_TRACE_LEVEL_ERROR,
7694 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7695 elem_id, elem_len, left);
7696 return;
7697 }
7698 if (IE_EID_VENDOR == elem_id)
7699 {
7700 /* skipping the VSIE's which we don't want to include or
7701 * it will be included by existing code
7702 */
7703 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7704#ifdef WLAN_FEATURE_WFD
7705 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7706#endif
7707 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7708 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7709 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7710 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7711 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7712 {
7713 ielen = ptr[1] + 2;
7714 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7715 {
7716 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7717 *total_ielen += ielen;
7718 }
7719 else
7720 {
7721 hddLog( VOS_TRACE_LEVEL_ERROR,
7722 "IE Length is too big "
7723 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7724 elem_id, elem_len, *total_ielen);
7725 }
7726 }
7727 }
7728
7729 left -= elem_len;
7730 ptr += (elem_len + 2);
7731 }
7732 return;
7733}
7734
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007735#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007736static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7737 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007738#else
7739static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7740 struct cfg80211_beacon_data *params)
7741#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007742{
7743 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307744 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007746 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007747
7748 genie = vos_mem_malloc(MAX_GENIE_LEN);
7749
7750 if(genie == NULL) {
7751
7752 return -ENOMEM;
7753 }
7754
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307755 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7756 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307758 hddLog(LOGE,
7759 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307760 ret = -EINVAL;
7761 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 }
7763
7764#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307765 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7766 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7767 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307768 hddLog(LOGE,
7769 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307770 ret = -EINVAL;
7771 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 }
7773#endif
7774
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307775 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7776 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307778 hddLog(LOGE,
7779 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307780 ret = -EINVAL;
7781 goto done;
7782 }
7783
7784 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7785 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007786 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007788
7789 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7790 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7791 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7792 {
7793 hddLog(LOGE,
7794 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007795 ret = -EINVAL;
7796 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 }
7798
7799 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7800 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7801 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7802 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7803 ==eHAL_STATUS_FAILURE)
7804 {
7805 hddLog(LOGE,
7806 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007807 ret = -EINVAL;
7808 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 }
7810
7811 // Added for ProResp IE
7812 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7813 {
7814 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7815 u8 probe_rsp_ie_len[3] = {0};
7816 u8 counter = 0;
7817 /* Check Probe Resp Length if it is greater then 255 then Store
7818 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7819 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7820 Store More then 255 bytes into One Variable.
7821 */
7822 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7823 {
7824 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7825 {
7826 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7827 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7828 }
7829 else
7830 {
7831 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7832 rem_probe_resp_ie_len = 0;
7833 }
7834 }
7835
7836 rem_probe_resp_ie_len = 0;
7837
7838 if (probe_rsp_ie_len[0] > 0)
7839 {
7840 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7841 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7842 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7843 probe_rsp_ie_len[0], NULL,
7844 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7845 {
7846 hddLog(LOGE,
7847 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007848 ret = -EINVAL;
7849 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 }
7851 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7852 }
7853
7854 if (probe_rsp_ie_len[1] > 0)
7855 {
7856 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7857 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7858 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7859 probe_rsp_ie_len[1], NULL,
7860 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7861 {
7862 hddLog(LOGE,
7863 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007864 ret = -EINVAL;
7865 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 }
7867 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7868 }
7869
7870 if (probe_rsp_ie_len[2] > 0)
7871 {
7872 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7873 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7874 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7875 probe_rsp_ie_len[2], NULL,
7876 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7877 {
7878 hddLog(LOGE,
7879 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007880 ret = -EINVAL;
7881 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 }
7883 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7884 }
7885
7886 if (probe_rsp_ie_len[1] == 0 )
7887 {
7888 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7889 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7890 eANI_BOOLEAN_FALSE) )
7891 {
7892 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007893 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 }
7895 }
7896
7897 if (probe_rsp_ie_len[2] == 0 )
7898 {
7899 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7900 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7901 eANI_BOOLEAN_FALSE) )
7902 {
7903 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007904 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007905 }
7906 }
7907
7908 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7909 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7910 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7911 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7912 == eHAL_STATUS_FAILURE)
7913 {
7914 hddLog(LOGE,
7915 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007916 ret = -EINVAL;
7917 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 }
7919 }
7920 else
7921 {
7922 // Reset WNI_CFG_PROBE_RSP Flags
7923 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7924
7925 hddLog(VOS_TRACE_LEVEL_INFO,
7926 "%s: No Probe Response IE received in set beacon",
7927 __func__);
7928 }
7929
7930 // Added for AssocResp IE
7931 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7932 {
7933 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7934 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7935 params->assocresp_ies_len, NULL,
7936 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7937 {
7938 hddLog(LOGE,
7939 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007940 ret = -EINVAL;
7941 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007942 }
7943
7944 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7945 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7946 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7947 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7948 == eHAL_STATUS_FAILURE)
7949 {
7950 hddLog(LOGE,
7951 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007952 ret = -EINVAL;
7953 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 }
7955 }
7956 else
7957 {
7958 hddLog(VOS_TRACE_LEVEL_INFO,
7959 "%s: No Assoc Response IE received in set beacon",
7960 __func__);
7961
7962 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7963 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7964 eANI_BOOLEAN_FALSE) )
7965 {
7966 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007967 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 }
7969 }
7970
Jeff Johnsone7245742012-09-05 17:12:55 -07007971done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307973 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007974}
Jeff Johnson295189b2012-06-20 16:38:30 -07007975
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307976/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 * FUNCTION: wlan_hdd_validate_operation_channel
7978 * called by wlan_hdd_cfg80211_start_bss() and
7979 * wlan_hdd_cfg80211_set_channel()
7980 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307981 * channel list.
7982 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007983VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007984{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307985
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 v_U32_t num_ch = 0;
7987 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7988 u32 indx = 0;
7989 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307990 v_U8_t fValidChannel = FALSE, count = 0;
7991 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307992
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7994
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307995 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307997 /* Validate the channel */
7998 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308000 if ( channel == rfChannels[count].channelNum )
8001 {
8002 fValidChannel = TRUE;
8003 break;
8004 }
8005 }
8006 if (fValidChannel != TRUE)
8007 {
8008 hddLog(VOS_TRACE_LEVEL_ERROR,
8009 "%s: Invalid Channel [%d]", __func__, channel);
8010 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 }
8012 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308013 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308015 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8016 valid_ch, &num_ch))
8017 {
8018 hddLog(VOS_TRACE_LEVEL_ERROR,
8019 "%s: failed to get valid channel list", __func__);
8020 return VOS_STATUS_E_FAILURE;
8021 }
8022 for (indx = 0; indx < num_ch; indx++)
8023 {
8024 if (channel == valid_ch[indx])
8025 {
8026 break;
8027 }
8028 }
8029
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308030 if (indx >= num_ch)
8031 {
8032 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8033 {
8034 eCsrBand band;
8035 unsigned int freq;
8036
8037 sme_GetFreqBand(hHal, &band);
8038
8039 if (eCSR_BAND_5G == band)
8040 {
8041#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8042 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8043 {
8044 freq = ieee80211_channel_to_frequency(channel,
8045 IEEE80211_BAND_2GHZ);
8046 }
8047 else
8048 {
8049 freq = ieee80211_channel_to_frequency(channel,
8050 IEEE80211_BAND_5GHZ);
8051 }
8052#else
8053 freq = ieee80211_channel_to_frequency(channel);
8054#endif
8055 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8056 return VOS_STATUS_SUCCESS;
8057 }
8058 }
8059
8060 hddLog(VOS_TRACE_LEVEL_ERROR,
8061 "%s: Invalid Channel [%d]", __func__, channel);
8062 return VOS_STATUS_E_FAILURE;
8063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308065
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308067
Jeff Johnson295189b2012-06-20 16:38:30 -07008068}
8069
Viral Modi3a32cc52013-02-08 11:14:52 -08008070/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308071 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008072 * This function is used to set the channel number
8073 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308074static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008075 struct ieee80211_channel *chan,
8076 enum nl80211_channel_type channel_type
8077 )
8078{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308079 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008080 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008081 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008082 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308083 hdd_context_t *pHddCtx;
8084 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008085
8086 ENTER();
8087
8088 if( NULL == dev )
8089 {
8090 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008091 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008092 return -ENODEV;
8093 }
8094 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308095
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8097 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8098 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008099 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308100 "%s: device_mode = %s (%d) freq = %d", __func__,
8101 hdd_device_modetoString(pAdapter->device_mode),
8102 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308103
8104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8105 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308106 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308108 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008109 }
8110
8111 /*
8112 * Do freq to chan conversion
8113 * TODO: for 11a
8114 */
8115
8116 channel = ieee80211_frequency_to_channel(freq);
8117
8118 /* Check freq range */
8119 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8120 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8121 {
8122 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008123 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008124 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8125 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8126 return -EINVAL;
8127 }
8128
8129 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8130
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308131 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8132 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008133 {
8134 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8135 {
8136 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008137 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008138 return -EINVAL;
8139 }
8140 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8141 "%s: set channel to [%d] for device mode =%d",
8142 __func__, channel,pAdapter->device_mode);
8143 }
8144 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08008145 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08008146 )
8147 {
8148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8149 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
8150 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8151
8152 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
8153 {
8154 /* Link is up then return cant set channel*/
8155 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008156 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008157 return -EINVAL;
8158 }
8159
8160 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
8161 pHddStaCtx->conn_info.operationChannel = channel;
8162 pRoamProfile->ChannelInfo.ChannelList =
8163 &pHddStaCtx->conn_info.operationChannel;
8164 }
8165 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08008166 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08008167 )
8168 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308169 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8170 {
8171 if(VOS_STATUS_SUCCESS !=
8172 wlan_hdd_validate_operation_channel(pAdapter,channel))
8173 {
8174 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008175 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308176 return -EINVAL;
8177 }
8178 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
8179 }
8180 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08008181 {
8182 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
8183
8184 /* If auto channel selection is configured as enable/ 1 then ignore
8185 channel set by supplicant
8186 */
8187 if ( cfg_param->apAutoChannelSelection )
8188 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308189 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
8190 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08008191 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308192 "%s: set channel to auto channel (0) for device mode =%s (%d)",
8193 __func__, hdd_device_modetoString(pAdapter->device_mode),
8194 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08008195 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308196 else
8197 {
8198 if(VOS_STATUS_SUCCESS !=
8199 wlan_hdd_validate_operation_channel(pAdapter,channel))
8200 {
8201 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008202 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308203 return -EINVAL;
8204 }
8205 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
8206 }
Viral Modi3a32cc52013-02-08 11:14:52 -08008207 }
8208 }
8209 else
8210 {
8211 hddLog(VOS_TRACE_LEVEL_FATAL,
8212 "%s: Invalid device mode failed to set valid channel", __func__);
8213 return -EINVAL;
8214 }
8215 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308216 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008217}
8218
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308219static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
8220 struct net_device *dev,
8221 struct ieee80211_channel *chan,
8222 enum nl80211_channel_type channel_type
8223 )
8224{
8225 int ret;
8226
8227 vos_ssr_protect(__func__);
8228 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
8229 vos_ssr_unprotect(__func__);
8230
8231 return ret;
8232}
8233
Jeff Johnson295189b2012-06-20 16:38:30 -07008234#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8235static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
8236 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008237#else
8238static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
8239 struct cfg80211_beacon_data *params,
8240 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308241 enum nl80211_hidden_ssid hidden_ssid,
8242 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008243#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008244{
8245 tsap_Config_t *pConfig;
8246 beacon_data_t *pBeacon = NULL;
8247 struct ieee80211_mgmt *pMgmt_frame;
8248 v_U8_t *pIe=NULL;
8249 v_U16_t capab_info;
8250 eCsrAuthType RSNAuthType;
8251 eCsrEncryptionType RSNEncryptType;
8252 eCsrEncryptionType mcRSNEncryptType;
8253 int status = VOS_STATUS_SUCCESS;
8254 tpWLAN_SAPEventCB pSapEventCallback;
8255 hdd_hostapd_state_t *pHostapdState;
8256 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
8257 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308258 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308260 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08008262 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05308263 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07008264 v_BOOL_t MFPCapable = VOS_FALSE;
8265 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308266 v_BOOL_t sapEnable11AC =
8267 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 ENTER();
8269
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308270 iniConfig = pHddCtx->cfg_ini;
8271
Jeff Johnson295189b2012-06-20 16:38:30 -07008272 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
8273
8274 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8275
8276 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8277
8278 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8279
8280 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
8281
8282 //channel is already set in the set_channel Call back
8283 //pConfig->channel = pCommitConfig->channel;
8284
8285 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308286 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
8288
8289 pConfig->dtim_period = pBeacon->dtim_period;
8290
Arif Hussain6d2a3322013-11-17 19:50:10 -08008291 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07008292 pConfig->dtim_period);
8293
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08008294 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07008295 {
8296 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05308298 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
8299 {
8300 tANI_BOOLEAN restartNeeded;
8301 pConfig->ieee80211d = 1;
8302 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
8303 sme_setRegInfo(hHal, pConfig->countryCode);
8304 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
8305 }
8306 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07008308 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07008309 pConfig->ieee80211d = 1;
8310 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
8311 sme_setRegInfo(hHal, pConfig->countryCode);
8312 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07008313 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008314 else
8315 {
8316 pConfig->ieee80211d = 0;
8317 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308318 /*
8319 * If auto channel is configured i.e. channel is 0,
8320 * so skip channel validation.
8321 */
8322 if( AUTO_CHANNEL_SELECT != pConfig->channel )
8323 {
8324 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
8325 {
8326 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008327 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308328 return -EINVAL;
8329 }
8330 }
8331 else
8332 {
8333 if(1 != pHddCtx->is_dynamic_channel_range_set)
8334 {
8335 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
8336 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
8337 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
8338 }
8339 pHddCtx->is_dynamic_channel_range_set = 0;
8340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008342 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 {
8344 pConfig->ieee80211d = 0;
8345 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308346
8347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8348 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8349 pConfig->authType = eSAP_OPEN_SYSTEM;
8350 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8351 pConfig->authType = eSAP_SHARED_KEY;
8352 else
8353 pConfig->authType = eSAP_AUTO_SWITCH;
8354#else
8355 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8356 pConfig->authType = eSAP_OPEN_SYSTEM;
8357 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8358 pConfig->authType = eSAP_SHARED_KEY;
8359 else
8360 pConfig->authType = eSAP_AUTO_SWITCH;
8361#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008362
8363 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308364
8365 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
8367
8368 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
8369
8370 /*Set wps station to configured*/
8371 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
8372
8373 if(pIe)
8374 {
8375 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
8376 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008377 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07008378 return -EINVAL;
8379 }
8380 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
8381 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008382 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 /* Check 15 bit of WPS IE as it contain information for wps state
8384 * WPS state
8385 */
8386 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
8387 {
8388 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
8389 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
8390 {
8391 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
8392 }
8393 }
8394 }
8395 else
8396 {
8397 pConfig->wps_state = SAP_WPS_DISABLED;
8398 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308399 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
c_hpothufe599e92014-06-16 11:38:55 +05308401 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8402 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8403 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
8404 eCSR_ENCRYPT_TYPE_NONE;
8405
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 pConfig->RSNWPAReqIELength = 0;
8407 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308408 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 WLAN_EID_RSN);
8410 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308411 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8413 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8414 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308415 /* The actual processing may eventually be more extensive than
8416 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 * by the app.
8418 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308419 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8421 &RSNEncryptType,
8422 &mcRSNEncryptType,
8423 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008424 &MFPCapable,
8425 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 pConfig->pRSNWPAReqIE[1]+2,
8427 pConfig->pRSNWPAReqIE );
8428
8429 if( VOS_STATUS_SUCCESS == status )
8430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308431 /* Now copy over all the security attributes you have
8432 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 * */
8434 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8435 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8436 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8437 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308438 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008439 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8441 }
8442 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308443
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8445 pBeacon->tail, pBeacon->tail_len);
8446
8447 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
8448 {
8449 if (pConfig->pRSNWPAReqIE)
8450 {
8451 /*Mixed mode WPA/WPA2*/
8452 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
8453 pConfig->RSNWPAReqIELength += pIe[1] + 2;
8454 }
8455 else
8456 {
8457 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8458 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8459 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308460 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8462 &RSNEncryptType,
8463 &mcRSNEncryptType,
8464 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008465 &MFPCapable,
8466 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 pConfig->pRSNWPAReqIE[1]+2,
8468 pConfig->pRSNWPAReqIE );
8469
8470 if( VOS_STATUS_SUCCESS == status )
8471 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308472 /* Now copy over all the security attributes you have
8473 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 * */
8475 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8476 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8477 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8478 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308479 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008480 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8482 }
8483 }
8484 }
8485
Jeff Johnson4416a782013-03-25 14:17:50 -07008486 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
8487 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
8488 return -EINVAL;
8489 }
8490
Jeff Johnson295189b2012-06-20 16:38:30 -07008491 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
8492
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008493#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 if (params->ssid != NULL)
8495 {
8496 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
8497 pConfig->SSIDinfo.ssid.length = params->ssid_len;
8498 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8499 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8500 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008501#else
8502 if (ssid != NULL)
8503 {
8504 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
8505 pConfig->SSIDinfo.ssid.length = ssid_len;
8506 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8507 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8508 }
8509#endif
8510
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308511 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308513
Jeff Johnson295189b2012-06-20 16:38:30 -07008514 /* default value */
8515 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
8516 pConfig->num_accept_mac = 0;
8517 pConfig->num_deny_mac = 0;
8518
8519 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8520 pBeacon->tail, pBeacon->tail_len);
8521
8522 /* pIe for black list is following form:
8523 type : 1 byte
8524 length : 1 byte
8525 OUI : 4 bytes
8526 acl type : 1 byte
8527 no of mac addr in black list: 1 byte
8528 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 */
8530 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 {
8532 pConfig->SapMacaddr_acl = pIe[6];
8533 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008534 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308536 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8537 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8539 for (i = 0; i < pConfig->num_deny_mac; i++)
8540 {
8541 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8542 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008544 }
8545 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8546 pBeacon->tail, pBeacon->tail_len);
8547
8548 /* pIe for white list is following form:
8549 type : 1 byte
8550 length : 1 byte
8551 OUI : 4 bytes
8552 acl type : 1 byte
8553 no of mac addr in white list: 1 byte
8554 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308555 */
8556 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 {
8558 pConfig->SapMacaddr_acl = pIe[6];
8559 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008560 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308562 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8563 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008564 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8565 for (i = 0; i < pConfig->num_accept_mac; i++)
8566 {
8567 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8568 acl_entry++;
8569 }
8570 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308571
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8573
Jeff Johnsone7245742012-09-05 17:12:55 -07008574#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008575 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308576 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8577 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308578 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8579 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008580 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8581 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308582 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8583 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008584 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308585 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008586 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308587 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008588
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308589 /* If ACS disable and selected channel <= 14
8590 * OR
8591 * ACS enabled and ACS operating band is choosen as 2.4
8592 * AND
8593 * VHT in 2.4G Disabled
8594 * THEN
8595 * Fallback to 11N mode
8596 */
8597 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8598 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308599 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308600 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008601 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308602 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8603 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008604 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8605 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008606 }
8607#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308608
Jeff Johnson295189b2012-06-20 16:38:30 -07008609 // ht_capab is not what the name conveys,this is used for protection bitmap
8610 pConfig->ht_capab =
8611 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8612
8613 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8614 {
8615 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8616 return -EINVAL;
8617 }
8618
8619 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308620 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8622 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308623 pConfig->obssProtEnabled =
8624 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625
Chet Lanctot8cecea22014-02-11 19:09:36 -08008626#ifdef WLAN_FEATURE_11W
8627 pConfig->mfpCapable = MFPCapable;
8628 pConfig->mfpRequired = MFPRequired;
8629 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8630 pConfig->mfpCapable, pConfig->mfpRequired);
8631#endif
8632
Arif Hussain6d2a3322013-11-17 19:50:10 -08008633 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008635 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8636 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8637 (int)pConfig->channel);
8638 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8639 pConfig->SapHw_mode, pConfig->privacy,
8640 pConfig->authType);
8641 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8642 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8643 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8644 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008645
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308646 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 {
8648 //Bss already started. just return.
8649 //TODO Probably it should update some beacon params.
8650 hddLog( LOGE, "Bss Already started...Ignore the request");
8651 EXIT();
8652 return 0;
8653 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308654
Agarwal Ashish51325b52014-06-16 16:50:49 +05308655 if (vos_max_concurrent_connections_reached()) {
8656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8657 return -EINVAL;
8658 }
8659
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 pConfig->persona = pHostapdAdapter->device_mode;
8661
Peng Xu2446a892014-09-05 17:21:18 +05308662 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8663 if ( NULL != psmeConfig)
8664 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308665 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308666 sme_GetConfigParam(hHal, psmeConfig);
8667 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308668#ifdef WLAN_FEATURE_AP_HT40_24G
8669 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8670 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8671 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8672 {
8673 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8674 sme_UpdateConfig (hHal, psmeConfig);
8675 }
8676#endif
Peng Xu2446a892014-09-05 17:21:18 +05308677 vos_mem_free(psmeConfig);
8678 }
Peng Xuafc34e32014-09-25 13:23:55 +05308679 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308680
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 pSapEventCallback = hdd_hostapd_SAPEventCB;
8682 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8683 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8684 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008685 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 return -EINVAL;
8687 }
8688
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308689 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8691
8692 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308693
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308695 {
8696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008697 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008698 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 VOS_ASSERT(0);
8700 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308701
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308703 /* Initialize WMM configuation */
8704 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308705 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008706
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008707#ifdef WLAN_FEATURE_P2P_DEBUG
8708 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8709 {
8710 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8711 {
8712 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8713 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008714 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008715 }
8716 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8717 {
8718 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8719 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008720 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008721 }
8722 }
8723#endif
8724
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 pHostapdState->bCommit = TRUE;
8726 EXIT();
8727
8728 return 0;
8729}
8730
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008731#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308732static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308733 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 struct beacon_parameters *params)
8735{
8736 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308737 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308738 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739
8740 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308741
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8743 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8744 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308745 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8746 hdd_device_modetoString(pAdapter->device_mode),
8747 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008748
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8750 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308751 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308753 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008754 }
8755
Agarwal Ashish51325b52014-06-16 16:50:49 +05308756 if (vos_max_concurrent_connections_reached()) {
8757 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8758 return -EINVAL;
8759 }
8760
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308761 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 )
8764 {
8765 beacon_data_t *old,*new;
8766
8767 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308768
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308770 {
8771 hddLog(VOS_TRACE_LEVEL_WARN,
8772 FL("already beacon info added to session(%d)"),
8773 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308775 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008776
8777 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8778
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308779 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 {
8781 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008782 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 return -EINVAL;
8784 }
8785
8786 pAdapter->sessionCtx.ap.beacon = new;
8787
8788 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8789 }
8790
8791 EXIT();
8792 return status;
8793}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308794
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308795static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8796 struct net_device *dev,
8797 struct beacon_parameters *params)
8798{
8799 int ret;
8800
8801 vos_ssr_protect(__func__);
8802 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8803 vos_ssr_unprotect(__func__);
8804
8805 return ret;
8806}
8807
8808static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 struct net_device *dev,
8810 struct beacon_parameters *params)
8811{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308813 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8814 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308815 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008816
8817 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308818
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308819 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8820 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8821 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8823 __func__, hdd_device_modetoString(pAdapter->device_mode),
8824 pAdapter->device_mode);
8825
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8827 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308828 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008829 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308830 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008831 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308832
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308833 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308835 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 {
8837 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308838
Jeff Johnson295189b2012-06-20 16:38:30 -07008839 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308840
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308842 {
8843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8844 FL("session(%d) old and new heads points to NULL"),
8845 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308847 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008848
8849 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8850
8851 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308852 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008853 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008854 return -EINVAL;
8855 }
8856
8857 pAdapter->sessionCtx.ap.beacon = new;
8858
8859 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8860 }
8861
8862 EXIT();
8863 return status;
8864}
8865
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308866static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8867 struct net_device *dev,
8868 struct beacon_parameters *params)
8869{
8870 int ret;
8871
8872 vos_ssr_protect(__func__);
8873 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8874 vos_ssr_unprotect(__func__);
8875
8876 return ret;
8877}
8878
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008879#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8880
8881#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308882static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008884#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308885static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008886 struct net_device *dev)
8887#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008888{
8889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008890 hdd_context_t *pHddCtx = NULL;
8891 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308892 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308893 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008894
8895 ENTER();
8896
8897 if (NULL == pAdapter)
8898 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008900 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 return -ENODEV;
8902 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008903
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308904 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8905 TRACE_CODE_HDD_CFG80211_STOP_AP,
8906 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308907 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8908 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308909 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308911 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008912 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008913
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008914 pScanInfo = &pHddCtx->scan_info;
8915
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8917 __func__, hdd_device_modetoString(pAdapter->device_mode),
8918 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008919
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308920 ret = wlan_hdd_scan_abort(pAdapter);
8921
Girish Gowli4bf7a632014-06-12 13:42:11 +05308922 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008923 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8925 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308926
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308927 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008928 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8930 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008931
Jeff Johnsone7245742012-09-05 17:12:55 -07008932 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308933 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008934 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308935 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008936 }
8937
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308938 /* Delete all associated STAs before stopping AP/P2P GO */
8939 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308940 hdd_hostapd_stop(dev);
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 )
8945 {
8946 beacon_data_t *old;
8947
8948 old = pAdapter->sessionCtx.ap.beacon;
8949
8950 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308951 {
8952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8953 FL("session(%d) beacon data points to NULL"),
8954 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308956 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008957
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008959
8960 mutex_lock(&pHddCtx->sap_lock);
8961 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8962 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008963 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 {
8965 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8966
8967 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8968
8969 if (!VOS_IS_STATUS_SUCCESS(status))
8970 {
8971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008972 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008973 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308974 }
8975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008976 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308977 /* BSS stopped, clear the active sessions for this device mode */
8978 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008979 }
8980 mutex_unlock(&pHddCtx->sap_lock);
8981
8982 if(status != VOS_STATUS_SUCCESS)
8983 {
8984 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008985 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008986 return -EINVAL;
8987 }
8988
Jeff Johnson4416a782013-03-25 14:17:50 -07008989 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8991 ==eHAL_STATUS_FAILURE)
8992 {
8993 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008994 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 }
8996
Jeff Johnson4416a782013-03-25 14:17:50 -07008997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8999 eANI_BOOLEAN_FALSE) )
9000 {
9001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 }
9004
9005 // Reset WNI_CFG_PROBE_RSP Flags
9006 wlan_hdd_reset_prob_rspies(pAdapter);
9007
9008 pAdapter->sessionCtx.ap.beacon = NULL;
9009 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009010#ifdef WLAN_FEATURE_P2P_DEBUG
9011 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9012 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9013 {
9014 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9015 "GO got removed");
9016 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9017 }
9018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 }
9020 EXIT();
9021 return status;
9022}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9025static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9026 struct net_device *dev)
9027{
9028 int ret;
9029
9030 vos_ssr_protect(__func__);
9031 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9032 vos_ssr_unprotect(__func__);
9033
9034 return ret;
9035}
9036#else
9037static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9038 struct net_device *dev)
9039{
9040 int ret;
9041
9042 vos_ssr_protect(__func__);
9043 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9044 vos_ssr_unprotect(__func__);
9045
9046 return ret;
9047}
9048#endif
9049
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009050#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9051
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309052static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309053 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009054 struct cfg80211_ap_settings *params)
9055{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309056 hdd_adapter_t *pAdapter;
9057 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309058 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009059
9060 ENTER();
9061
Girish Gowlib143d7a2015-02-18 19:39:55 +05309062 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009063 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309065 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309066 return -ENODEV;
9067 }
9068
9069 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9070 if (NULL == pAdapter)
9071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309073 "%s: HDD adapter is Null", __func__);
9074 return -ENODEV;
9075 }
9076
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9078 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9079 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309080 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309083 "%s: HDD adapter magic is invalid", __func__);
9084 return -ENODEV;
9085 }
9086
9087 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309088 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309089 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309090 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309091 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309092 }
9093
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309094 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9095 __func__, hdd_device_modetoString(pAdapter->device_mode),
9096 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309097
9098 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009099 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009100 )
9101 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309102 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009103
9104 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309105
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009106 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309107 {
9108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9109 FL("already beacon info added to session(%d)"),
9110 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009111 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309112 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009113
Girish Gowlib143d7a2015-02-18 19:39:55 +05309114#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9115 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9116 &new,
9117 &params->beacon);
9118#else
9119 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9120 &new,
9121 &params->beacon,
9122 params->dtim_period);
9123#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009124
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309125 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009126 {
9127 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309128 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009129 return -EINVAL;
9130 }
9131 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009133 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9134#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9135 params->channel, params->channel_type);
9136#else
9137 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9138#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009139#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009140 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309141 params->ssid_len, params->hidden_ssid,
9142 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009143 }
9144
9145 EXIT();
9146 return status;
9147}
9148
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309149static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
9150 struct net_device *dev,
9151 struct cfg80211_ap_settings *params)
9152{
9153 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009154
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309155 vos_ssr_protect(__func__);
9156 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
9157 vos_ssr_unprotect(__func__);
9158
9159 return ret;
9160}
9161
9162static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009163 struct net_device *dev,
9164 struct cfg80211_beacon_data *params)
9165{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309167 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309168 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009169
9170 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309171
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9173 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
9174 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009176 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309177
9178 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9179 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309180 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009181 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309182 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009183 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009184
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309185 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009186 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309187 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009188 {
9189 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309190
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009191 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309192
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009193 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309194 {
9195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9196 FL("session(%d) beacon data points to NULL"),
9197 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009198 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309199 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009200
9201 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
9202
9203 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309204 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009205 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009206 return -EINVAL;
9207 }
9208
9209 pAdapter->sessionCtx.ap.beacon = new;
9210
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309211 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
9212 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009213 }
9214
9215 EXIT();
9216 return status;
9217}
9218
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309219static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
9220 struct net_device *dev,
9221 struct cfg80211_beacon_data *params)
9222{
9223 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009224
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309225 vos_ssr_protect(__func__);
9226 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
9227 vos_ssr_unprotect(__func__);
9228
9229 return ret;
9230}
9231
9232#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05309234static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 struct net_device *dev,
9236 struct bss_parameters *params)
9237{
9238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309239 hdd_context_t *pHddCtx;
9240 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009241
9242 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309243
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309244 if (NULL == pAdapter)
9245 {
9246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9247 "%s: HDD adapter is Null", __func__);
9248 return -ENODEV;
9249 }
9250 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309251 ret = wlan_hdd_validate_context(pHddCtx);
9252 if (0 != ret)
9253 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309254 return ret;
9255 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309256 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9257 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
9258 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309259 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9260 __func__, hdd_device_modetoString(pAdapter->device_mode),
9261 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009262
9263 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 {
9267 /* ap_isolate == -1 means that in change bss, upper layer doesn't
9268 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309269 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 {
9271 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 }
9274
9275 EXIT();
9276 return 0;
9277}
9278
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05309279static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
9280 struct net_device *dev,
9281 struct bss_parameters *params)
9282{
9283 int ret;
9284
9285 vos_ssr_protect(__func__);
9286 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
9287 vos_ssr_unprotect(__func__);
9288
9289 return ret;
9290}
Kiet Lam10841362013-11-01 11:36:50 +05309291/* FUNCTION: wlan_hdd_change_country_code_cd
9292* to wait for contry code completion
9293*/
9294void* wlan_hdd_change_country_code_cb(void *pAdapter)
9295{
9296 hdd_adapter_t *call_back_pAdapter = pAdapter;
9297 complete(&call_back_pAdapter->change_country_code);
9298 return NULL;
9299}
9300
Jeff Johnson295189b2012-06-20 16:38:30 -07009301/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309302 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
9304 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309305int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 struct net_device *ndev,
9307 enum nl80211_iftype type,
9308 u32 *flags,
9309 struct vif_params *params
9310 )
9311{
9312 struct wireless_dev *wdev;
9313 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009314 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07009315 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tCsrRoamProfile *pRoamProfile = NULL;
9317 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309318 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 eMib_dot11DesiredBssType connectedBssType;
9320 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309321 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009322
9323 ENTER();
9324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309325 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009326 {
9327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9328 "%s: Adapter context is null", __func__);
9329 return VOS_STATUS_E_FAILURE;
9330 }
9331
9332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9333 if (!pHddCtx)
9334 {
9335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9336 "%s: HDD context is null", __func__);
9337 return VOS_STATUS_E_FAILURE;
9338 }
9339
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9341 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
9342 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309343 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309344 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309346 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 }
9348
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9350 __func__, hdd_device_modetoString(pAdapter->device_mode),
9351 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009352
Agarwal Ashish51325b52014-06-16 16:50:49 +05309353 if (vos_max_concurrent_connections_reached()) {
9354 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9355 return -EINVAL;
9356 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309357 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 wdev = ndev->ieee80211_ptr;
9359
9360#ifdef WLAN_BTAMP_FEATURE
9361 if((NL80211_IFTYPE_P2P_CLIENT == type)||
9362 (NL80211_IFTYPE_ADHOC == type)||
9363 (NL80211_IFTYPE_AP == type)||
9364 (NL80211_IFTYPE_P2P_GO == type))
9365 {
9366 pHddCtx->isAmpAllowed = VOS_FALSE;
9367 // stop AMP traffic
9368 status = WLANBAP_StopAmp();
9369 if(VOS_STATUS_SUCCESS != status )
9370 {
9371 pHddCtx->isAmpAllowed = VOS_TRUE;
9372 hddLog(VOS_TRACE_LEVEL_FATAL,
9373 "%s: Failed to stop AMP", __func__);
9374 return -EINVAL;
9375 }
9376 }
9377#endif //WLAN_BTAMP_FEATURE
9378 /* Reset the current device mode bit mask*/
9379 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
9380
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05309381 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
9382 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
9383 (type == NL80211_IFTYPE_P2P_GO)))
9384 {
9385 /* Notify Mode change in case of concurrency.
9386 * Below function invokes TDLS teardown Functionality Since TDLS is
9387 * not Supported in case of concurrency i.e Once P2P session
9388 * is detected disable offchannel and teardown TDLS links
9389 */
9390 hddLog(LOG1,
9391 FL("Device mode = %d Interface type = %d"),
9392 pAdapter->device_mode, type);
9393 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
9394 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05309395
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07009398 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 )
9400 {
9401 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009402 if (!pWextState)
9403 {
9404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9405 "%s: pWextState is null", __func__);
9406 return VOS_STATUS_E_FAILURE;
9407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 pRoamProfile = &pWextState->roamProfile;
9409 LastBSSType = pRoamProfile->BSSType;
9410
9411 switch (type)
9412 {
9413 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 hddLog(VOS_TRACE_LEVEL_INFO,
9416 "%s: setting interface Type to INFRASTRUCTURE", __func__);
9417 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009418#ifdef WLAN_FEATURE_11AC
9419 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
9420 {
9421 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
9422 }
9423#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07009425 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009427 //Check for sub-string p2p to confirm its a p2p interface
9428 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309429 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05309430#ifdef FEATURE_WLAN_TDLS
9431 mutex_lock(&pHddCtx->tdls_lock);
9432 wlan_hdd_tdls_exit(pAdapter, TRUE);
9433 mutex_unlock(&pHddCtx->tdls_lock);
9434#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009435 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9436 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9437 }
9438 else
9439 {
9440 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05309444
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 case NL80211_IFTYPE_ADHOC:
9446 hddLog(VOS_TRACE_LEVEL_INFO,
9447 "%s: setting interface Type to ADHOC", __func__);
9448 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
9449 pRoamProfile->phyMode =
9450 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07009451 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05309453 hdd_set_ibss_ops( pAdapter );
9454 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05309455
9456 status = hdd_sta_id_hash_attach(pAdapter);
9457 if (VOS_STATUS_SUCCESS != status) {
9458 hddLog(VOS_TRACE_LEVEL_ERROR,
9459 FL("Failed to initialize hash for IBSS"));
9460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 break;
9462
9463 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009464 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 {
9466 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9467 "%s: setting interface Type to %s", __func__,
9468 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
9469
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009470 //Cancel any remain on channel for GO mode
9471 if (NL80211_IFTYPE_P2P_GO == type)
9472 {
9473 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
9474 }
Mohit Khanna0f232092012-09-11 14:46:08 -07009475 if (NL80211_IFTYPE_AP == type)
9476 {
9477 /* As Loading WLAN Driver one interface being created for p2p device
9478 * address. This will take one HW STA and the max number of clients
9479 * that can connect to softAP will be reduced by one. so while changing
9480 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
9481 * interface as it is not required in SoftAP mode.
9482 */
9483
9484 // Get P2P Adapter
9485 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
9486
9487 if (pP2pAdapter)
9488 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309489 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05309490 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07009491 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
9492 }
9493 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05309494 //Disable IMPS & BMPS for SAP/GO
9495 if(VOS_STATUS_E_FAILURE ==
9496 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
9497 {
9498 //Fail to Exit BMPS
9499 VOS_ASSERT(0);
9500 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05309501
9502 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
9503
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309504#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07009505
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309506 /* A Mutex Lock is introduced while changing the mode to
9507 * protect the concurrent access for the Adapters by TDLS
9508 * module.
9509 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309510 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309511#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05309513 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9516 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309517#ifdef FEATURE_WLAN_TDLS
9518 mutex_unlock(&pHddCtx->tdls_lock);
9519#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009520 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
9521 (pConfig->apRandomBssidEnabled))
9522 {
9523 /* To meet Android requirements create a randomized
9524 MAC address of the form 02:1A:11:Fx:xx:xx */
9525 get_random_bytes(&ndev->dev_addr[3], 3);
9526 ndev->dev_addr[0] = 0x02;
9527 ndev->dev_addr[1] = 0x1A;
9528 ndev->dev_addr[2] = 0x11;
9529 ndev->dev_addr[3] |= 0xF0;
9530 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9531 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009532 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9533 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009534 }
9535
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 hdd_set_ap_ops( pAdapter->dev );
9537
Kiet Lam10841362013-11-01 11:36:50 +05309538 /* This is for only SAP mode where users can
9539 * control country through ini.
9540 * P2P GO follows station country code
9541 * acquired during the STA scanning. */
9542 if((NL80211_IFTYPE_AP == type) &&
9543 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9544 {
9545 int status = 0;
9546 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9547 "%s: setting country code from INI ", __func__);
9548 init_completion(&pAdapter->change_country_code);
9549 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9550 (void *)(tSmeChangeCountryCallback)
9551 wlan_hdd_change_country_code_cb,
9552 pConfig->apCntryCode, pAdapter,
9553 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309554 eSIR_FALSE,
9555 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309556 if (eHAL_STATUS_SUCCESS == status)
9557 {
9558 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309559 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309560 &pAdapter->change_country_code,
9561 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309562 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309563 {
9564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309565 FL("SME Timed out while setting country code %ld"),
9566 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009567
9568 if (pHddCtx->isLogpInProgress)
9569 {
9570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9571 "%s: LOGP in Progress. Ignore!!!", __func__);
9572 return -EAGAIN;
9573 }
Kiet Lam10841362013-11-01 11:36:50 +05309574 }
9575 }
9576 else
9577 {
9578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009579 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309580 return -EINVAL;
9581 }
9582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 status = hdd_init_ap_mode(pAdapter);
9584 if(status != VOS_STATUS_SUCCESS)
9585 {
9586 hddLog(VOS_TRACE_LEVEL_FATAL,
9587 "%s: Error initializing the ap mode", __func__);
9588 return -EINVAL;
9589 }
9590 hdd_set_conparam(1);
9591
Nirav Shah7e3c8132015-06-22 23:51:42 +05309592 status = hdd_sta_id_hash_attach(pAdapter);
9593 if (VOS_STATUS_SUCCESS != status)
9594 {
9595 hddLog(VOS_TRACE_LEVEL_ERROR,
9596 FL("Failed to initialize hash for AP"));
9597 return -EINVAL;
9598 }
9599
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 /*interface type changed update in wiphy structure*/
9601 if(wdev)
9602 {
9603 wdev->iftype = type;
9604 pHddCtx->change_iface = type;
9605 }
9606 else
9607 {
9608 hddLog(VOS_TRACE_LEVEL_ERROR,
9609 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9610 return -EINVAL;
9611 }
9612 goto done;
9613 }
9614
9615 default:
9616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9617 __func__);
9618 return -EOPNOTSUPP;
9619 }
9620 }
9621 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 )
9624 {
9625 switch(type)
9626 {
9627 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309630
9631 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309632#ifdef FEATURE_WLAN_TDLS
9633
9634 /* A Mutex Lock is introduced while changing the mode to
9635 * protect the concurrent access for the Adapters by TDLS
9636 * module.
9637 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309638 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309639#endif
c_hpothu002231a2015-02-05 14:58:51 +05309640 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009642 //Check for sub-string p2p to confirm its a p2p interface
9643 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009644 {
9645 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9646 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9647 }
9648 else
9649 {
9650 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009652 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 hdd_set_conparam(0);
9654 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9656 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309657#ifdef FEATURE_WLAN_TDLS
9658 mutex_unlock(&pHddCtx->tdls_lock);
9659#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309660 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 if( VOS_STATUS_SUCCESS != status )
9662 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009663 /* In case of JB, for P2P-GO, only change interface will be called,
9664 * This is the right place to enable back bmps_imps()
9665 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309666 if (pHddCtx->hdd_wlan_suspended)
9667 {
9668 hdd_set_pwrparams(pHddCtx);
9669 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009670 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 goto done;
9672 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9676 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009677 goto done;
9678 default:
9679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9680 __func__);
9681 return -EOPNOTSUPP;
9682
9683 }
9684
9685 }
9686 else
9687 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309688 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9689 __func__, hdd_device_modetoString(pAdapter->device_mode),
9690 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 return -EOPNOTSUPP;
9692 }
9693
9694
9695 if(pRoamProfile)
9696 {
9697 if ( LastBSSType != pRoamProfile->BSSType )
9698 {
9699 /*interface type changed update in wiphy structure*/
9700 wdev->iftype = type;
9701
9702 /*the BSS mode changed, We need to issue disconnect
9703 if connected or in IBSS disconnect state*/
9704 if ( hdd_connGetConnectedBssType(
9705 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9706 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9707 {
9708 /*need to issue a disconnect to CSR.*/
9709 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9710 if( eHAL_STATUS_SUCCESS ==
9711 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9712 pAdapter->sessionId,
9713 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9714 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309715 ret = wait_for_completion_interruptible_timeout(
9716 &pAdapter->disconnect_comp_var,
9717 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9718 if (ret <= 0)
9719 {
9720 hddLog(VOS_TRACE_LEVEL_ERROR,
9721 FL("wait on disconnect_comp_var failed %ld"), ret);
9722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 }
9724 }
9725 }
9726 }
9727
9728done:
9729 /*set bitmask based on updated value*/
9730 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009731
9732 /* Only STA mode support TM now
9733 * all other mode, TM feature should be disabled */
9734 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9735 (~VOS_STA & pHddCtx->concurrency_mode) )
9736 {
9737 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9738 }
9739
Jeff Johnson295189b2012-06-20 16:38:30 -07009740#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309741 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309742 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 {
9744 //we are ok to do AMP
9745 pHddCtx->isAmpAllowed = VOS_TRUE;
9746 }
9747#endif //WLAN_BTAMP_FEATURE
9748 EXIT();
9749 return 0;
9750}
9751
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309752/*
9753 * FUNCTION: wlan_hdd_cfg80211_change_iface
9754 * wrapper function to protect the actual implementation from SSR.
9755 */
9756int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9757 struct net_device *ndev,
9758 enum nl80211_iftype type,
9759 u32 *flags,
9760 struct vif_params *params
9761 )
9762{
9763 int ret;
9764
9765 vos_ssr_protect(__func__);
9766 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9767 vos_ssr_unprotect(__func__);
9768
9769 return ret;
9770}
9771
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009772#ifdef FEATURE_WLAN_TDLS
9773static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309774 struct net_device *dev,
9775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9776 const u8 *mac,
9777#else
9778 u8 *mac,
9779#endif
9780 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009781{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009782 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009783 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309784 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309785 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309786 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309787 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009788
9789 ENTER();
9790
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309791 if (!dev) {
9792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9793 return -EINVAL;
9794 }
9795
9796 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9797 if (!pAdapter) {
9798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9799 return -EINVAL;
9800 }
9801
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309802 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009803 {
9804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9805 "Invalid arguments");
9806 return -EINVAL;
9807 }
Hoonki Lee27511902013-03-14 18:19:06 -07009808
9809 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9810 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9811 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009813 "%s: TDLS mode is disabled OR not enabled in FW."
9814 MAC_ADDRESS_STR " Request declined.",
9815 __func__, MAC_ADDR_ARRAY(mac));
9816 return -ENOTSUPP;
9817 }
9818
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009819 if (pHddCtx->isLogpInProgress)
9820 {
9821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9822 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309823 wlan_hdd_tdls_set_link_status(pAdapter,
9824 mac,
9825 eTDLS_LINK_IDLE,
9826 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009827 return -EBUSY;
9828 }
9829
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309830 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309831 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009832
9833 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009835 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9836 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309837 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009838 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009839 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309840 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009841
9842 /* in add station, we accept existing valid staId if there is */
9843 if ((0 == update) &&
9844 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9845 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009846 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009848 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009849 " link_status %d. staId %d. add station ignored.",
9850 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9851 return 0;
9852 }
9853 /* in change station, we accept only when staId is valid */
9854 if ((1 == update) &&
9855 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9856 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9857 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009859 "%s: " MAC_ADDRESS_STR
9860 " link status %d. staId %d. change station %s.",
9861 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9862 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9863 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009864 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009865
9866 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309867 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009868 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9870 "%s: " MAC_ADDRESS_STR
9871 " TDLS setup is ongoing. Request declined.",
9872 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009873 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009874 }
9875
9876 /* first to check if we reached to maximum supported TDLS peer.
9877 TODO: for now, return -EPERM looks working fine,
9878 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309879 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9880 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009881 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9883 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309884 " TDLS Max peer already connected. Request declined."
9885 " Num of peers (%d), Max allowed (%d).",
9886 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9887 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009888 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009889 }
9890 else
9891 {
9892 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309893 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009894 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009895 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9897 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9898 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009899 return -EPERM;
9900 }
9901 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009902 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309903 wlan_hdd_tdls_set_link_status(pAdapter,
9904 mac,
9905 eTDLS_LINK_CONNECTING,
9906 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009907
Jeff Johnsond75fe012013-04-06 10:53:06 -07009908 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309909 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009910 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009912 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009913 if(StaParams->htcap_present)
9914 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009916 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009918 "ht_capa->extended_capabilities: %0x",
9919 StaParams->HTCap.extendedHtCapInfo);
9920 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009922 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009924 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009925 if(StaParams->vhtcap_present)
9926 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009928 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9929 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9930 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9931 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009932 {
9933 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009935 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009937 "[%d]: %x ", i, StaParams->supported_rates[i]);
9938 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009939 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309940 else if ((1 == update) && (NULL == StaParams))
9941 {
9942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9943 "%s : update is true, but staParams is NULL. Error!", __func__);
9944 return -EPERM;
9945 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009946
9947 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9948
9949 if (!update)
9950 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309951 /*Before adding sta make sure that device exited from BMPS*/
9952 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9953 {
9954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9955 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9956 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9957 if (status != VOS_STATUS_SUCCESS) {
9958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9959 }
9960 }
9961
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309962 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009963 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309964 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309965 hddLog(VOS_TRACE_LEVEL_ERROR,
9966 FL("Failed to add TDLS peer STA. Enable Bmps"));
9967 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309968 return -EPERM;
9969 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009970 }
9971 else
9972 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309973 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009974 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309975 if (ret != eHAL_STATUS_SUCCESS) {
9976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9977 return -EPERM;
9978 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009979 }
9980
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309981 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009982 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9983
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309984 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009985 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309987 "%s: timeout waiting for tdls add station indication %ld",
9988 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009989 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009990 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309991
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009992 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9993 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009995 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009996 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009997 }
9998
9999 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010000
10001error:
Atul Mittal115287b2014-07-08 13:26:33 +053010002 wlan_hdd_tdls_set_link_status(pAdapter,
10003 mac,
10004 eTDLS_LINK_IDLE,
10005 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010006 return -EPERM;
10007
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010008}
10009#endif
10010
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010011static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010013#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10014 const u8 *mac,
10015#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010016 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010017#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 struct station_parameters *params)
10019{
10020 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010021 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010022 hdd_context_t *pHddCtx;
10023 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010025 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010026#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010027 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010028 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010029 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010030#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010031
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010032 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010033
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010034 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010035 if ((NULL == pAdapter))
10036 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010038 "invalid adapter ");
10039 return -EINVAL;
10040 }
10041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10043 TRACE_CODE_HDD_CHANGE_STATION,
10044 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010045 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010046
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010047 ret = wlan_hdd_validate_context(pHddCtx);
10048 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010049 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010050 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010051 }
10052
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010053 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10054
10055 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010056 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10058 "invalid HDD station context");
10059 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010060 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10062
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010063 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10064 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010065 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010066 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 WLANTL_STA_AUTHENTICATED);
10070
Gopichand Nakkala29149562013-05-10 21:43:41 +053010071 if (status != VOS_STATUS_SUCCESS)
10072 {
10073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10074 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10075 return -EINVAL;
10076 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 }
10078 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010079 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10080 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010081#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010082 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10083 StaParams.capability = params->capability;
10084 StaParams.uapsd_queues = params->uapsd_queues;
10085 StaParams.max_sp = params->max_sp;
10086
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010087 /* Convert (first channel , number of channels) tuple to
10088 * the total list of channels. This goes with the assumption
10089 * that if the first channel is < 14, then the next channels
10090 * are an incremental of 1 else an incremental of 4 till the number
10091 * of channels.
10092 */
10093 if (0 != params->supported_channels_len) {
10094 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10095 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10096 {
10097 int wifi_chan_index;
10098 StaParams.supported_channels[j] = params->supported_channels[i];
10099 wifi_chan_index =
10100 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10101 no_of_channels = params->supported_channels[i+1];
10102 for(k=1; k <= no_of_channels; k++)
10103 {
10104 StaParams.supported_channels[j+1] =
10105 StaParams.supported_channels[j] + wifi_chan_index;
10106 j+=1;
10107 }
10108 }
10109 StaParams.supported_channels_len = j;
10110 }
10111 vos_mem_copy(StaParams.supported_oper_classes,
10112 params->supported_oper_classes,
10113 params->supported_oper_classes_len);
10114 StaParams.supported_oper_classes_len =
10115 params->supported_oper_classes_len;
10116
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010117 if (0 != params->ext_capab_len)
10118 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10119 sizeof(StaParams.extn_capability));
10120
10121 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010122 {
10123 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010124 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010125 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010126
10127 StaParams.supported_rates_len = params->supported_rates_len;
10128
10129 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10130 * The supported_rates array , for all the structures propogating till Add Sta
10131 * to the firmware has to be modified , if the supplicant (ieee80211) is
10132 * modified to send more rates.
10133 */
10134
10135 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10136 */
10137 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
10138 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
10139
10140 if (0 != StaParams.supported_rates_len) {
10141 int i = 0;
10142 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
10143 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010145 "Supported Rates with Length %d", StaParams.supported_rates_len);
10146 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010148 "[%d]: %0x", i, StaParams.supported_rates[i]);
10149 }
10150
10151 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010152 {
10153 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010154 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010155 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010156
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010157 if (0 != params->ext_capab_len ) {
10158 /*Define A Macro : TODO Sunil*/
10159 if ((1<<4) & StaParams.extn_capability[3]) {
10160 isBufSta = 1;
10161 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010162 /* TDLS Channel Switching Support */
10163 if ((1<<6) & StaParams.extn_capability[3]) {
10164 isOffChannelSupported = 1;
10165 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010166 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010167 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
10168 &StaParams, isBufSta,
10169 isOffChannelSupported);
10170
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053010171 if (VOS_STATUS_SUCCESS != status) {
10172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10173 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
10174 return -EINVAL;
10175 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010176 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
10177
10178 if (VOS_STATUS_SUCCESS != status) {
10179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10180 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
10181 return -EINVAL;
10182 }
10183 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010184#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053010185 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010186 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 return status;
10188}
10189
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010190#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
10191static int wlan_hdd_change_station(struct wiphy *wiphy,
10192 struct net_device *dev,
10193 const u8 *mac,
10194 struct station_parameters *params)
10195#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010196static int wlan_hdd_change_station(struct wiphy *wiphy,
10197 struct net_device *dev,
10198 u8 *mac,
10199 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010200#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010201{
10202 int ret;
10203
10204 vos_ssr_protect(__func__);
10205 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
10206 vos_ssr_unprotect(__func__);
10207
10208 return ret;
10209}
10210
Jeff Johnson295189b2012-06-20 16:38:30 -070010211/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010212 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010213 * This function is used to initialize the key information
10214 */
10215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010216static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 struct net_device *ndev,
10218 u8 key_index, bool pairwise,
10219 const u8 *mac_addr,
10220 struct key_params *params
10221 )
10222#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010223static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 struct net_device *ndev,
10225 u8 key_index, const u8 *mac_addr,
10226 struct key_params *params
10227 )
10228#endif
10229{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 tCsrRoamSetKey setKey;
10232 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010233 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010234 v_U32_t roamId= 0xFF;
10235 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 hdd_hostapd_state_t *pHostapdState;
10237 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010238 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010239 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010240
10241 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010242
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10244 TRACE_CODE_HDD_CFG80211_ADD_KEY,
10245 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010246 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10247 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010248 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010249 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010250 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010251 }
10252
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010253 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10254 __func__, hdd_device_modetoString(pAdapter->device_mode),
10255 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010256
10257 if (CSR_MAX_NUM_KEY <= key_index)
10258 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 key_index);
10261
10262 return -EINVAL;
10263 }
10264
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010265 if (CSR_MAX_KEY_LEN < params->key_len)
10266 {
10267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
10268 params->key_len);
10269
10270 return -EINVAL;
10271 }
10272
10273 hddLog(VOS_TRACE_LEVEL_INFO,
10274 "%s: called with key index = %d & key length %d",
10275 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010276
10277 /*extract key idx, key len and key*/
10278 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10279 setKey.keyId = key_index;
10280 setKey.keyLength = params->key_len;
10281 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
10282
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010283 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 {
10285 case WLAN_CIPHER_SUITE_WEP40:
10286 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10287 break;
10288
10289 case WLAN_CIPHER_SUITE_WEP104:
10290 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
10291 break;
10292
10293 case WLAN_CIPHER_SUITE_TKIP:
10294 {
10295 u8 *pKey = &setKey.Key[0];
10296 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
10297
10298 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
10299
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010300 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070010301
10302 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010303 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 |--------------|----------|----------|
10305 <---16bytes---><--8bytes--><--8bytes-->
10306
10307 */
10308 /*Sme expects the 32 bytes key to be in the below order
10309
10310 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010311 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 |--------------|----------|----------|
10313 <---16bytes---><--8bytes--><--8bytes-->
10314 */
10315 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010316 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070010317
10318 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010319 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010320
10321 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010322 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010323
10324
10325 break;
10326 }
10327
10328 case WLAN_CIPHER_SUITE_CCMP:
10329 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
10330 break;
10331
10332#ifdef FEATURE_WLAN_WAPI
10333 case WLAN_CIPHER_SUITE_SMS4:
10334 {
10335 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10336 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
10337 params->key, params->key_len);
10338 return 0;
10339 }
10340#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010341
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010342#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 case WLAN_CIPHER_SUITE_KRK:
10344 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
10345 break;
10346#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010347
10348#ifdef WLAN_FEATURE_11W
10349 case WLAN_CIPHER_SUITE_AES_CMAC:
10350 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070010351 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070010352#endif
10353
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010357 status = -EOPNOTSUPP;
10358 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 }
10360
10361 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
10362 __func__, setKey.encType);
10363
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010364 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070010365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10366 (!pairwise)
10367#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010368 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070010369#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010370 )
10371 {
10372 /* set group key*/
10373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10374 "%s- %d: setting Broadcast key",
10375 __func__, __LINE__);
10376 setKey.keyDirection = eSIR_RX_ONLY;
10377 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10378 }
10379 else
10380 {
10381 /* set pairwise key*/
10382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10383 "%s- %d: setting pairwise key",
10384 __func__, __LINE__);
10385 setKey.keyDirection = eSIR_TX_RX;
10386 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10387 }
10388 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
10389 {
10390 setKey.keyDirection = eSIR_TX_RX;
10391 /*Set the group key*/
10392 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10393 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070010394
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010395 if ( 0 != status )
10396 {
10397 hddLog(VOS_TRACE_LEVEL_ERROR,
10398 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010399 status = -EINVAL;
10400 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010401 }
10402 /*Save the keys here and call sme_RoamSetKey for setting
10403 the PTK after peer joins the IBSS network*/
10404 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
10405 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010406 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010407 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053010408 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
10409 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
10410 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010412 if( pHostapdState->bssState == BSS_START )
10413 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010414 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10415 vos_status = wlan_hdd_check_ula_done(pAdapter);
10416
10417 if ( vos_status != VOS_STATUS_SUCCESS )
10418 {
10419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10420 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10421 __LINE__, vos_status );
10422
10423 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10424
10425 status = -EINVAL;
10426 goto end;
10427 }
10428
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 status = WLANSAP_SetKeySta( pVosContext, &setKey);
10430
10431 if ( status != eHAL_STATUS_SUCCESS )
10432 {
10433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10434 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10435 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010436 status = -EINVAL;
10437 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 }
10439 }
10440
10441 /* Saving WEP keys */
10442 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
10443 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
10444 {
10445 //Save the wep key in ap context. Issue setkey after the BSS is started.
10446 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10447 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
10448 }
10449 else
10450 {
10451 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010452 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
10454 }
10455 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010456 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
10457 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 {
10459 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10461
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10463 if (!pairwise)
10464#else
10465 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
10466#endif
10467 {
10468 /* set group key*/
10469 if (pHddStaCtx->roam_info.deferKeyComplete)
10470 {
10471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10472 "%s- %d: Perform Set key Complete",
10473 __func__, __LINE__);
10474 hdd_PerformRoamSetKeyComplete(pAdapter);
10475 }
10476 }
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
10479
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080010480 pWextState->roamProfile.Keys.defaultIndex = key_index;
10481
10482
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010483 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 params->key, params->key_len);
10485
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010486
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10488
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010489 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 __func__, setKey.peerMac[0], setKey.peerMac[1],
10492 setKey.peerMac[2], setKey.peerMac[3],
10493 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 setKey.keyDirection);
10495
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010496 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053010497
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010498 if ( vos_status != VOS_STATUS_SUCCESS )
10499 {
10500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10502 __LINE__, vos_status );
10503
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010504 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010505
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010506 status = -EINVAL;
10507 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010508
10509 }
10510
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010511#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010512 /* The supplicant may attempt to set the PTK once pre-authentication
10513 is done. Save the key in the UMAC and include it in the ADD BSS
10514 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010515 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010516 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010517 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010518 hddLog(VOS_TRACE_LEVEL_INFO_MED,
10519 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010520 status = 0;
10521 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010522 }
10523 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
10524 {
10525 hddLog(VOS_TRACE_LEVEL_ERROR,
10526 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010527 status = -EINVAL;
10528 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010529 }
10530#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010531
10532 /* issue set key request to SME*/
10533 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10534 pAdapter->sessionId, &setKey, &roamId );
10535
10536 if ( 0 != status )
10537 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010538 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10540 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010541 status = -EINVAL;
10542 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 }
10544
10545
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010546 /* in case of IBSS as there was no information available about WEP keys during
10547 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010549 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10550 !( ( IW_AUTH_KEY_MGMT_802_1X
10551 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10553 )
10554 &&
10555 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10556 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10557 )
10558 )
10559 {
10560 setKey.keyDirection = eSIR_RX_ONLY;
10561 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10562
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010563 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010565 __func__, setKey.peerMac[0], setKey.peerMac[1],
10566 setKey.peerMac[2], setKey.peerMac[3],
10567 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 setKey.keyDirection);
10569
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010570 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 pAdapter->sessionId, &setKey, &roamId );
10572
10573 if ( 0 != status )
10574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010575 hddLog(VOS_TRACE_LEVEL_ERROR,
10576 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 __func__, status);
10578 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010579 status = -EINVAL;
10580 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 }
10582 }
10583 }
10584
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010585end:
10586 /* Need to clear any trace of key value in the memory.
10587 * Thus zero out the memory even though it is local
10588 * variable.
10589 */
10590 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010591 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010592 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010593}
10594
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10596static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10597 struct net_device *ndev,
10598 u8 key_index, bool pairwise,
10599 const u8 *mac_addr,
10600 struct key_params *params
10601 )
10602#else
10603static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10604 struct net_device *ndev,
10605 u8 key_index, const u8 *mac_addr,
10606 struct key_params *params
10607 )
10608#endif
10609{
10610 int ret;
10611 vos_ssr_protect(__func__);
10612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10613 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10614 mac_addr, params);
10615#else
10616 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10617 params);
10618#endif
10619 vos_ssr_unprotect(__func__);
10620
10621 return ret;
10622}
10623
Jeff Johnson295189b2012-06-20 16:38:30 -070010624/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010625 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010626 * This function is used to get the key information
10627 */
10628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010629static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010630 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010632 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 const u8 *mac_addr, void *cookie,
10634 void (*callback)(void *cookie, struct key_params*)
10635 )
10636#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010637static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 struct net_device *ndev,
10640 u8 key_index, const u8 *mac_addr, void *cookie,
10641 void (*callback)(void *cookie, struct key_params*)
10642 )
10643#endif
10644{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010645 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010646 hdd_wext_state_t *pWextState = NULL;
10647 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010649 hdd_context_t *pHddCtx;
10650 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010651
10652 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010653
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010654 if (NULL == pAdapter)
10655 {
10656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10657 "%s: HDD adapter is Null", __func__);
10658 return -ENODEV;
10659 }
10660
10661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10662 ret = wlan_hdd_validate_context(pHddCtx);
10663 if (0 != ret)
10664 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010665 return ret;
10666 }
10667
10668 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10669 pRoamProfile = &(pWextState->roamProfile);
10670
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010671 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10672 __func__, hdd_device_modetoString(pAdapter->device_mode),
10673 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010674
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 memset(&params, 0, sizeof(params));
10676
10677 if (CSR_MAX_NUM_KEY <= key_index)
10678 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010681 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010682
10683 switch(pRoamProfile->EncryptionType.encryptionType[0])
10684 {
10685 case eCSR_ENCRYPT_TYPE_NONE:
10686 params.cipher = IW_AUTH_CIPHER_NONE;
10687 break;
10688
10689 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10690 case eCSR_ENCRYPT_TYPE_WEP40:
10691 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10692 break;
10693
10694 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10695 case eCSR_ENCRYPT_TYPE_WEP104:
10696 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10697 break;
10698
10699 case eCSR_ENCRYPT_TYPE_TKIP:
10700 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10701 break;
10702
10703 case eCSR_ENCRYPT_TYPE_AES:
10704 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10705 break;
10706
10707 default:
10708 params.cipher = IW_AUTH_CIPHER_NONE;
10709 break;
10710 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010711
c_hpothuaaf19692014-05-17 17:01:48 +053010712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10713 TRACE_CODE_HDD_CFG80211_GET_KEY,
10714 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10717 params.seq_len = 0;
10718 params.seq = NULL;
10719 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10720 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010721 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010722 return 0;
10723}
10724
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10726static int wlan_hdd_cfg80211_get_key(
10727 struct wiphy *wiphy,
10728 struct net_device *ndev,
10729 u8 key_index, bool pairwise,
10730 const u8 *mac_addr, void *cookie,
10731 void (*callback)(void *cookie, struct key_params*)
10732 )
10733#else
10734static int wlan_hdd_cfg80211_get_key(
10735 struct wiphy *wiphy,
10736 struct net_device *ndev,
10737 u8 key_index, const u8 *mac_addr, void *cookie,
10738 void (*callback)(void *cookie, struct key_params*)
10739 )
10740#endif
10741{
10742 int ret;
10743
10744 vos_ssr_protect(__func__);
10745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10746 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10747 mac_addr, cookie, callback);
10748#else
10749 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10750 callback);
10751#endif
10752 vos_ssr_unprotect(__func__);
10753
10754 return ret;
10755}
10756
Jeff Johnson295189b2012-06-20 16:38:30 -070010757/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010758 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010759 * This function is used to delete the key information
10760 */
10761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010762static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010764 u8 key_index,
10765 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010766 const u8 *mac_addr
10767 )
10768#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010769static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 struct net_device *ndev,
10771 u8 key_index,
10772 const u8 *mac_addr
10773 )
10774#endif
10775{
10776 int status = 0;
10777
10778 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010779 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010780 //it is observed that this is invalidating peer
10781 //key index whenever re-key is done. This is affecting data link.
10782 //It should be ok to ignore del_key.
10783#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010784 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10785 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010786 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10787 tCsrRoamSetKey setKey;
10788 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010789
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 ENTER();
10791
10792 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10793 __func__,pAdapter->device_mode);
10794
10795 if (CSR_MAX_NUM_KEY <= key_index)
10796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010798 key_index);
10799
10800 return -EINVAL;
10801 }
10802
10803 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10804 setKey.keyId = key_index;
10805
10806 if (mac_addr)
10807 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10808 else
10809 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10810
10811 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10812
10813 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010815 )
10816 {
10817
10818 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10820 if( pHostapdState->bssState == BSS_START)
10821 {
10822 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010823
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 if ( status != eHAL_STATUS_SUCCESS )
10825 {
10826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10827 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10828 __LINE__, status );
10829 }
10830 }
10831 }
10832 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010833 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 )
10835 {
10836 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10837
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010838 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10839
10840 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010842 __func__, setKey.peerMac[0], setKey.peerMac[1],
10843 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010845 if(pAdapter->sessionCtx.station.conn_info.connState ==
10846 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010848 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010850
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 if ( 0 != status )
10852 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010853 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 "%s: sme_RoamSetKey failure, returned %d",
10855 __func__, status);
10856 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10857 return -EINVAL;
10858 }
10859 }
10860 }
10861#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010862 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 return status;
10864}
10865
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010866#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10867static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10868 struct net_device *ndev,
10869 u8 key_index,
10870 bool pairwise,
10871 const u8 *mac_addr
10872 )
10873#else
10874static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10875 struct net_device *ndev,
10876 u8 key_index,
10877 const u8 *mac_addr
10878 )
10879#endif
10880{
10881 int ret;
10882
10883 vos_ssr_protect(__func__);
10884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10885 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10886 mac_addr);
10887#else
10888 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10889#endif
10890 vos_ssr_unprotect(__func__);
10891
10892 return ret;
10893}
10894
Jeff Johnson295189b2012-06-20 16:38:30 -070010895/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010896 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 * This function is used to set the default tx key index
10898 */
10899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010900static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 struct net_device *ndev,
10902 u8 key_index,
10903 bool unicast, bool multicast)
10904#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010905static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 struct net_device *ndev,
10907 u8 key_index)
10908#endif
10909{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010910 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010911 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010912 hdd_wext_state_t *pWextState;
10913 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010914 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010915
10916 ENTER();
10917
Gopichand Nakkala29149562013-05-10 21:43:41 +053010918 if ((NULL == pAdapter))
10919 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010921 "invalid adapter");
10922 return -EINVAL;
10923 }
10924
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10926 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10927 pAdapter->sessionId, key_index));
10928
Gopichand Nakkala29149562013-05-10 21:43:41 +053010929 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10930 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10931
10932 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10933 {
10934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10935 "invalid Wext state or HDD context");
10936 return -EINVAL;
10937 }
10938
Arif Hussain6d2a3322013-11-17 19:50:10 -080010939 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010941
Jeff Johnson295189b2012-06-20 16:38:30 -070010942 if (CSR_MAX_NUM_KEY <= key_index)
10943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 key_index);
10946
10947 return -EINVAL;
10948 }
10949
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10951 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010952 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010953 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010954 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010955 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010959 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010961 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010962 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010963 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010964 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010966 {
10967 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010968 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010969
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 tCsrRoamSetKey setKey;
10971 v_U32_t roamId= 0xFF;
10972 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010973
10974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010975 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010976
Jeff Johnson295189b2012-06-20 16:38:30 -070010977 Keys->defaultIndex = (u8)key_index;
10978 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10979 setKey.keyId = key_index;
10980 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010981
10982 vos_mem_copy(&setKey.Key[0],
10983 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010984 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010985
Gopichand Nakkala29149562013-05-10 21:43:41 +053010986 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010987
10988 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 &pHddStaCtx->conn_info.bssId[0],
10990 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010991
Gopichand Nakkala29149562013-05-10 21:43:41 +053010992 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10993 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10994 eCSR_ENCRYPT_TYPE_WEP104)
10995 {
10996 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10997 even though ap is configured for WEP-40 encryption. In this canse the key length
10998 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10999 type(104) and switching encryption type to 40*/
11000 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11001 eCSR_ENCRYPT_TYPE_WEP40;
11002 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11003 eCSR_ENCRYPT_TYPE_WEP40;
11004 }
11005
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011006 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011010 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011012
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 if ( 0 != status )
11014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011015 hddLog(VOS_TRACE_LEVEL_ERROR,
11016 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 status);
11018 return -EINVAL;
11019 }
11020 }
11021 }
11022
11023 /* In SoftAp mode setting key direction for default mode */
11024 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11025 {
11026 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11027 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11028 (eCSR_ENCRYPT_TYPE_AES !=
11029 pWextState->roamProfile.EncryptionType.encryptionType[0])
11030 )
11031 {
11032 /* Saving key direction for default key index to TX default */
11033 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11034 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11035 }
11036 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011037 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 return status;
11039}
11040
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11042static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11043 struct net_device *ndev,
11044 u8 key_index,
11045 bool unicast, bool multicast)
11046#else
11047static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11048 struct net_device *ndev,
11049 u8 key_index)
11050#endif
11051{
11052 int ret;
11053 vos_ssr_protect(__func__);
11054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11055 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11056 multicast);
11057#else
11058 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11059#endif
11060 vos_ssr_unprotect(__func__);
11061
11062 return ret;
11063}
11064
Jeff Johnson295189b2012-06-20 16:38:30 -070011065/*
11066 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11067 * This function is used to inform the BSS details to nl80211 interface.
11068 */
11069static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11070 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11071{
11072 struct net_device *dev = pAdapter->dev;
11073 struct wireless_dev *wdev = dev->ieee80211_ptr;
11074 struct wiphy *wiphy = wdev->wiphy;
11075 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11076 int chan_no;
11077 int ie_length;
11078 const char *ie;
11079 unsigned int freq;
11080 struct ieee80211_channel *chan;
11081 int rssi = 0;
11082 struct cfg80211_bss *bss = NULL;
11083
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 if( NULL == pBssDesc )
11085 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011086 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 return bss;
11088 }
11089
11090 chan_no = pBssDesc->channelId;
11091 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11092 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11093
11094 if( NULL == ie )
11095 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 return bss;
11098 }
11099
11100#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11101 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11102 {
11103 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11104 }
11105 else
11106 {
11107 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11108 }
11109#else
11110 freq = ieee80211_channel_to_frequency(chan_no);
11111#endif
11112
11113 chan = __ieee80211_get_channel(wiphy, freq);
11114
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011115 if (!chan) {
11116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11117 return NULL;
11118 }
11119
Abhishek Singhaee43942014-06-16 18:55:47 +053011120 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011121
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011122 return cfg80211_inform_bss(wiphy, chan,
11123#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11124 CFG80211_BSS_FTYPE_UNKNOWN,
11125#endif
11126 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 pBssDesc->capabilityInfo,
11129 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011130 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011131}
11132
11133
11134
11135/*
11136 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
11137 * This function is used to inform the BSS details to nl80211 interface.
11138 */
11139struct cfg80211_bss*
11140wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
11141 tSirBssDescription *bss_desc
11142 )
11143{
11144 /*
11145 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
11146 already exists in bss data base of cfg80211 for that particular BSS ID.
11147 Using cfg80211_inform_bss_frame to update the bss entry instead of
11148 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
11149 now there is no possibility to get the mgmt(probe response) frame from PE,
11150 converting bss_desc to ieee80211_mgmt(probe response) and passing to
11151 cfg80211_inform_bss_frame.
11152 */
11153 struct net_device *dev = pAdapter->dev;
11154 struct wireless_dev *wdev = dev->ieee80211_ptr;
11155 struct wiphy *wiphy = wdev->wiphy;
11156 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011157#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
11158 qcom_ie_age *qie_age = NULL;
11159 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
11160#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 const char *ie =
11164 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
11165 unsigned int freq;
11166 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011167 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 struct cfg80211_bss *bss_status = NULL;
11169 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
11170 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070011171 hdd_context_t *pHddCtx;
11172 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070011173#ifdef WLAN_OPEN_SOURCE
11174 struct timespec ts;
11175#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011176
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011177
Wilson Yangf80a0542013-10-07 13:02:37 -070011178 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11179 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070011180 if (0 != status)
11181 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070011182 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011183 }
11184
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011185 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070011186 if (!mgmt)
11187 {
11188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11189 "%s: memory allocation failed ", __func__);
11190 return NULL;
11191 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070011192
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011194
11195#ifdef WLAN_OPEN_SOURCE
11196 /* Android does not want the timestamp from the frame.
11197 Instead it wants a monotonic increasing value */
11198 get_monotonic_boottime(&ts);
11199 mgmt->u.probe_resp.timestamp =
11200 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
11201#else
11202 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
11204 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070011205
11206#endif
11207
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
11209 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011210
11211#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
11212 /* GPS Requirement: need age ie per entry. Using vendor specific. */
11213 /* Assuming this is the last IE, copy at the end */
11214 ie_length -=sizeof(qcom_ie_age);
11215 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
11216 qie_age->element_id = QCOM_VENDOR_IE_ID;
11217 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
11218 qie_age->oui_1 = QCOM_OUI1;
11219 qie_age->oui_2 = QCOM_OUI2;
11220 qie_age->oui_3 = QCOM_OUI3;
11221 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
11222 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
11223#endif
11224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053011226 if (bss_desc->fProbeRsp)
11227 {
11228 mgmt->frame_control |=
11229 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
11230 }
11231 else
11232 {
11233 mgmt->frame_control |=
11234 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
11235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011236
11237#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011238 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
11240 {
11241 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11242 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
11245
11246 {
11247 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11248 }
11249 else
11250 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
11252 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 kfree(mgmt);
11254 return NULL;
11255 }
11256#else
11257 freq = ieee80211_channel_to_frequency(chan_no);
11258#endif
11259 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080011260 /*when the band is changed on the fly using the GUI, three things are done
11261 * 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)
11262 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
11263 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
11264 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
11265 * and discards the channels correponding to previous band and calls back with zero bss results.
11266 * 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
11267 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
11268 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
11269 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
11270 * So drop the bss and continue to next bss.
11271 */
11272 if(chan == NULL)
11273 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070011275 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080011276 return NULL;
11277 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053011278 /*To keep the rssi icon of the connected AP in the scan window
11279 *and the rssi icon of the wireless networks in sync
11280 * */
11281 if (( eConnectionState_Associated ==
11282 pAdapter->sessionCtx.station.conn_info.connState ) &&
11283 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
11284 pAdapter->sessionCtx.station.conn_info.bssId,
11285 WNI_CFG_BSSID_LEN)) &&
11286 (pHddCtx->hdd_wlan_suspended == FALSE))
11287 {
11288 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
11289 rssi = (pAdapter->rssi * 100);
11290 }
11291 else
11292 {
11293 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
11294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011295
Nirav Shah20ac06f2013-12-12 18:14:06 +053011296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053011297 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
11298 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053011299
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
11301 frame_len, rssi, GFP_KERNEL);
11302 kfree(mgmt);
11303 return bss_status;
11304}
11305
11306/*
11307 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
11308 * This function is used to update the BSS data base of CFG8011
11309 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011310struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 tCsrRoamInfo *pRoamInfo
11312 )
11313{
11314 tCsrRoamConnectedProfile roamProfile;
11315 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11316 struct cfg80211_bss *bss = NULL;
11317
11318 ENTER();
11319
11320 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
11321 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
11322
11323 if (NULL != roamProfile.pBssDesc)
11324 {
Girish Gowlif4b68022014-08-28 23:18:57 +053011325 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11326 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070011327
11328 if (NULL == bss)
11329 {
11330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
11331 __func__);
11332 }
11333
11334 sme_RoamFreeConnectProfile(hHal, &roamProfile);
11335 }
11336 else
11337 {
11338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
11339 __func__);
11340 }
11341 return bss;
11342}
11343
11344/*
11345 * FUNCTION: wlan_hdd_cfg80211_update_bss
11346 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
11348 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011350{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011351 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 tCsrScanResultInfo *pScanResult;
11353 eHalStatus status = 0;
11354 tScanResultHandle pResult;
11355 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011356 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011357 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011359
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11361 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
11362 NO_SESSION, pAdapter->sessionId));
11363
Wilson Yangf80a0542013-10-07 13:02:37 -070011364 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11365
11366 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 {
Wilson Yangf80a0542013-10-07 13:02:37 -070011368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11369 "%s:LOGP in Progress. Ignore!!!",__func__);
11370 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 }
11372
Wilson Yangf80a0542013-10-07 13:02:37 -070011373
11374 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053011375 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070011376 {
11377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11378 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
11379 return VOS_STATUS_E_PERM;
11380 }
11381
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011382 if (pAdapter->request != NULL)
11383 {
11384 if ((pAdapter->request->n_ssids == 1)
11385 && (pAdapter->request->ssids != NULL)
11386 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
11387 is_p2p_scan = true;
11388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011389 /*
11390 * start getting scan results and populate cgf80211 BSS database
11391 */
11392 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
11393
11394 /* no scan results */
11395 if (NULL == pResult)
11396 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
11398 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011399 wlan_hdd_get_frame_logs(pAdapter,
11400 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 return status;
11402 }
11403
11404 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
11405
11406 while (pScanResult)
11407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 /*
11409 * cfg80211_inform_bss() is not updating ie field of bss entry, if
11410 * entry already exists in bss data base of cfg80211 for that
11411 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
11412 * bss entry instead of cfg80211_inform_bss, But this call expects
11413 * mgmt packet as input. As of now there is no possibility to get
11414 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 * ieee80211_mgmt(probe response) and passing to c
11416 * fg80211_inform_bss_frame.
11417 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011418 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
11419 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
11420 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011421 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11422 continue; //Skip the non p2p bss entries
11423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11425 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011426
Jeff Johnson295189b2012-06-20 16:38:30 -070011427
11428 if (NULL == bss_status)
11429 {
11430 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011431 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 }
11433 else
11434 {
Yue Maf49ba872013-08-19 12:04:25 -070011435 cfg80211_put_bss(
11436#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
11437 wiphy,
11438#endif
11439 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 }
11441
11442 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11443 }
11444
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011445 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011446 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011447 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011448}
11449
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011450void
11451hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
11452{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011453 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080011454 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011455} /****** end hddPrintMacAddr() ******/
11456
11457void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011458hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011459{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011460 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011461 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011462 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
11463 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
11464 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011465} /****** end hddPrintPmkId() ******/
11466
11467//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
11468//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
11469
11470//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
11471//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
11472
11473#define dump_bssid(bssid) \
11474 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011475 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
11476 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011477 }
11478
11479#define dump_pmkid(pMac, pmkid) \
11480 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011481 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
11482 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011483 }
11484
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070011485#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011486/*
11487 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
11488 * This function is used to notify the supplicant of a new PMKSA candidate.
11489 */
11490int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011492 int index, bool preauth )
11493{
Jeff Johnsone7245742012-09-05 17:12:55 -070011494#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011495 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011496 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011497
11498 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070011499 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011500
11501 if( NULL == pRoamInfo )
11502 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011503 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011504 return -EINVAL;
11505 }
11506
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011507 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
11508 {
11509 dump_bssid(pRoamInfo->bssid);
11510 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011511 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011512 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011513#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011515}
11516#endif //FEATURE_WLAN_LFR
11517
Yue Maef608272013-04-08 23:09:17 -070011518#ifdef FEATURE_WLAN_LFR_METRICS
11519/*
11520 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
11521 * 802.11r/LFR metrics reporting function to report preauth initiation
11522 *
11523 */
11524#define MAX_LFR_METRICS_EVENT_LENGTH 100
11525VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
11526 tCsrRoamInfo *pRoamInfo)
11527{
11528 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11529 union iwreq_data wrqu;
11530
11531 ENTER();
11532
11533 if (NULL == pAdapter)
11534 {
11535 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11536 return VOS_STATUS_E_FAILURE;
11537 }
11538
11539 /* create the event */
11540 memset(&wrqu, 0, sizeof(wrqu));
11541 memset(metrics_notification, 0, sizeof(metrics_notification));
11542
11543 wrqu.data.pointer = metrics_notification;
11544 wrqu.data.length = scnprintf(metrics_notification,
11545 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11546 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11547
11548 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11549
11550 EXIT();
11551
11552 return VOS_STATUS_SUCCESS;
11553}
11554
11555/*
11556 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11557 * 802.11r/LFR metrics reporting function to report preauth completion
11558 * or failure
11559 */
11560VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11561 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11562{
11563 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11564 union iwreq_data wrqu;
11565
11566 ENTER();
11567
11568 if (NULL == pAdapter)
11569 {
11570 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11571 return VOS_STATUS_E_FAILURE;
11572 }
11573
11574 /* create the event */
11575 memset(&wrqu, 0, sizeof(wrqu));
11576 memset(metrics_notification, 0, sizeof(metrics_notification));
11577
11578 scnprintf(metrics_notification, sizeof(metrics_notification),
11579 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11580 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11581
11582 if (1 == preauth_status)
11583 strncat(metrics_notification, " TRUE", 5);
11584 else
11585 strncat(metrics_notification, " FALSE", 6);
11586
11587 wrqu.data.pointer = metrics_notification;
11588 wrqu.data.length = strlen(metrics_notification);
11589
11590 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11591
11592 EXIT();
11593
11594 return VOS_STATUS_SUCCESS;
11595}
11596
11597/*
11598 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11599 * 802.11r/LFR metrics reporting function to report handover initiation
11600 *
11601 */
11602VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11603 tCsrRoamInfo *pRoamInfo)
11604{
11605 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11606 union iwreq_data wrqu;
11607
11608 ENTER();
11609
11610 if (NULL == pAdapter)
11611 {
11612 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11613 return VOS_STATUS_E_FAILURE;
11614 }
11615
11616 /* create the event */
11617 memset(&wrqu, 0, sizeof(wrqu));
11618 memset(metrics_notification, 0, sizeof(metrics_notification));
11619
11620 wrqu.data.pointer = metrics_notification;
11621 wrqu.data.length = scnprintf(metrics_notification,
11622 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11623 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11624
11625 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11626
11627 EXIT();
11628
11629 return VOS_STATUS_SUCCESS;
11630}
11631#endif
11632
Jeff Johnson295189b2012-06-20 16:38:30 -070011633/*
11634 * FUNCTION: hdd_cfg80211_scan_done_callback
11635 * scanning callback function, called after finishing scan
11636 *
11637 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011638static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11640{
11641 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011644 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011645 struct cfg80211_scan_request *req = NULL;
11646 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011647 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011648 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011649 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011650 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011651
11652 ENTER();
11653
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011654 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011655 if (NULL == pHddCtx) {
11656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011657 goto allow_suspend;
11658 }
11659
11660 pScanInfo = &pHddCtx->scan_info;
11661
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 hddLog(VOS_TRACE_LEVEL_INFO,
11663 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011664 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 __func__, halHandle, pContext, (int) scanId, (int) status);
11666
Kiet Lamac06e2c2013-10-23 16:25:07 +053011667 pScanInfo->mScanPendingCounter = 0;
11668
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011670 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011671 &pScanInfo->scan_req_completion_event,
11672 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011673 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011675 hddLog(VOS_TRACE_LEVEL_ERROR,
11676 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011678 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 }
11680
Yue Maef608272013-04-08 23:09:17 -070011681 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 {
11683 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011684 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 }
11686
11687 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011688 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 {
11690 hddLog(VOS_TRACE_LEVEL_INFO,
11691 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011692 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 (int) scanId);
11694 }
11695
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011696 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 pAdapter);
11698
11699 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011701
11702
11703 /* If any client wait scan result through WEXT
11704 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011705 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 {
11707 /* The other scan request waiting for current scan finish
11708 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011709 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011711 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 }
11713 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011714 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 {
11716 struct net_device *dev = pAdapter->dev;
11717 union iwreq_data wrqu;
11718 int we_event;
11719 char *msg;
11720
11721 memset(&wrqu, '\0', sizeof(wrqu));
11722 we_event = SIOCGIWSCAN;
11723 msg = NULL;
11724 wireless_send_event(dev, we_event, &wrqu, msg);
11725 }
11726 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011727 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011728
11729 /* Get the Scan Req */
11730 req = pAdapter->request;
11731
11732 if (!req)
11733 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011734 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011735 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011736 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 }
11738
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011740 /* Scan is no longer pending */
11741 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011742
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011743 /* last_scan_timestamp is used to decide if new scan
11744 * is needed or not on station interface. If last station
11745 * scan time and new station scan time is less then
11746 * last_scan_timestamp ; driver will return cached scan.
11747 */
11748 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11749 {
11750 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11751
11752 if ( req->n_channels )
11753 {
11754 for (i = 0; i < req->n_channels ; i++ )
11755 {
11756 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11757 }
11758 /* store no of channel scanned */
11759 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11760 }
11761
11762 }
11763
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011764 /*
11765 * cfg80211_scan_done informing NL80211 about completion
11766 * of scanning
11767 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011768 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11769 {
11770 aborted = true;
11771 }
11772 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011773 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011774
Siddharth Bhal76972212014-10-15 16:22:51 +053011775 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11776 /* Generate new random mac addr for next scan */
11777 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11778 hdd_processSpoofMacAddrRequest(pHddCtx);
11779 }
11780
Jeff Johnsone7245742012-09-05 17:12:55 -070011781allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011782 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011783 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011784
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011785 /* Acquire wakelock to handle the case where APP's tries to suspend
11786 * immediatly after the driver gets connect request(i.e after scan)
11787 * from supplicant, this result in app's is suspending and not able
11788 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011789 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011790
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011791#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011792 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011793#endif
11794
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 EXIT();
11796 return 0;
11797}
11798
11799/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011800 * FUNCTION: hdd_isConnectionInProgress
11801 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011802 *
11803 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011804v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011805{
11806 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11807 hdd_station_ctx_t *pHddStaCtx = NULL;
11808 hdd_adapter_t *pAdapter = NULL;
11809 VOS_STATUS status = 0;
11810 v_U8_t staId = 0;
11811 v_U8_t *staMac = NULL;
11812
c_hpothu9b781ba2013-12-30 20:57:45 +053011813 if (TRUE == pHddCtx->btCoexModeSet)
11814 {
11815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011816 FL("BTCoex Mode operation in progress"));
11817 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011818 }
11819
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011820 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11821
11822 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11823 {
11824 pAdapter = pAdapterNode->pAdapter;
11825
11826 if( pAdapter )
11827 {
11828 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011829 "%s: Adapter with device mode %s (%d) exists",
11830 __func__, hdd_device_modetoString(pAdapter->device_mode),
11831 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011832 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011833 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11834 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11835 (eConnectionState_Connecting ==
11836 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11837 {
11838 hddLog(VOS_TRACE_LEVEL_ERROR,
11839 "%s: %p(%d) Connection is in progress", __func__,
11840 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11841 return VOS_TRUE;
11842 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011843 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011844 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011845 {
11846 hddLog(VOS_TRACE_LEVEL_ERROR,
11847 "%s: %p(%d) Reassociation is in progress", __func__,
11848 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11849 return VOS_TRUE;
11850 }
11851 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011852 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11853 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011854 {
11855 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11856 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011857 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011858 {
11859 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11860 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011861 "%s: client " MAC_ADDRESS_STR
11862 " is in the middle of WPS/EAPOL exchange.", __func__,
11863 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011864 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011865 }
11866 }
11867 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11868 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11869 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011870 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11871 ptSapContext pSapCtx = NULL;
11872 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11873 if(pSapCtx == NULL){
11874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11875 FL("psapCtx is NULL"));
11876 return VOS_FALSE;
11877 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011878 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11879 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011880 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11881 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011882 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011883 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011884
11885 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011886 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11887 "middle of WPS/EAPOL exchange.", __func__,
11888 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011889 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011890 }
11891 }
11892 }
11893 }
11894 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11895 pAdapterNode = pNext;
11896 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011897 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011898}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011899
11900/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011901 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011902 * this scan respond to scan trigger and update cfg80211 scan database
11903 * later, scan dump command can be used to recieve scan results
11904 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011905int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011906#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11907 struct net_device *dev,
11908#endif
11909 struct cfg80211_scan_request *request)
11910{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011911 hdd_adapter_t *pAdapter = NULL;
11912 hdd_context_t *pHddCtx = NULL;
11913 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011914 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011915 tCsrScanRequest scanRequest;
11916 tANI_U8 *channelList = NULL, i;
11917 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 int status;
11919 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011921 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011922 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011923 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011924 v_S7_t rssi=0;
11925 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011926
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11928 struct net_device *dev = NULL;
11929 if (NULL == request)
11930 {
11931 hddLog(VOS_TRACE_LEVEL_ERROR,
11932 "%s: scan req param null", __func__);
11933 return -EINVAL;
11934 }
11935 dev = request->wdev->netdev;
11936#endif
11937
11938 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11939 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11940 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11941
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 ENTER();
11943
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11945 __func__, hdd_device_modetoString(pAdapter->device_mode),
11946 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011948 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011949 if (0 != status)
11950 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011951 return status;
11952 }
11953
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011954 if (NULL == pwextBuf)
11955 {
11956 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11957 __func__);
11958 return -EIO;
11959 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011960 cfg_param = pHddCtx->cfg_ini;
11961 pScanInfo = &pHddCtx->scan_info;
11962
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011963 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11964 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11965 {
11966 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11967 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11968 }
11969
Jeff Johnson295189b2012-06-20 16:38:30 -070011970#ifdef WLAN_BTAMP_FEATURE
11971 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011972 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011974 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 "%s: No scanning when AMP is on", __func__);
11976 return -EOPNOTSUPP;
11977 }
11978#endif
11979 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011980 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011982 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011983 "%s: Not scanning on device_mode = %s (%d)",
11984 __func__, hdd_device_modetoString(pAdapter->device_mode),
11985 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 return -EOPNOTSUPP;
11987 }
11988
11989 if (TRUE == pScanInfo->mScanPending)
11990 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011991 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11992 {
11993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11994 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011995 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 }
11997
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011998 // Don't allow scan if PNO scan is going on.
11999 if (pHddCtx->isPnoEnable)
12000 {
12001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12002 FL("pno scan in progress"));
12003 return -EBUSY;
12004 }
12005
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012006 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012007 //Channel and action frame is pending
12008 //Otherwise Cancel Remain On Channel and allow Scan
12009 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012010 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012011 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012013 return -EBUSY;
12014 }
12015
Jeff Johnson295189b2012-06-20 16:38:30 -070012016 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12017 {
12018 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012019 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012021 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12023 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012024 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 "%s: MAX TM Level Scan not allowed", __func__);
12026 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012027 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 }
12029 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12030
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012031 /* Check if scan is allowed at this point of time.
12032 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012033 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012034 {
12035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12036 return -EBUSY;
12037 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012038
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12040
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012041 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12042 * Becasue of this, driver is assuming that this is not wildcard scan and so
12043 * is not aging out the scan results.
12044 */
12045 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012046 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012047 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012048 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012049
12050 if ((request->ssids) && (0 < request->n_ssids))
12051 {
12052 tCsrSSIDInfo *SsidInfo;
12053 int j;
12054 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12055 /* Allocate num_ssid tCsrSSIDInfo structure */
12056 SsidInfo = scanRequest.SSIDs.SSIDList =
12057 ( tCsrSSIDInfo *)vos_mem_malloc(
12058 request->n_ssids*sizeof(tCsrSSIDInfo));
12059
12060 if(NULL == scanRequest.SSIDs.SSIDList)
12061 {
12062 hddLog(VOS_TRACE_LEVEL_ERROR,
12063 "%s: memory alloc failed SSIDInfo buffer", __func__);
12064 return -ENOMEM;
12065 }
12066
12067 /* copy all the ssid's and their length */
12068 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12069 {
12070 /* get the ssid length */
12071 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12072 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12073 SsidInfo->SSID.length);
12074 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12075 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12076 j, SsidInfo->SSID.ssId);
12077 }
12078 /* set the scan type to active */
12079 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12080 }
12081 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012082 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12084 TRACE_CODE_HDD_CFG80211_SCAN,
12085 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 /* set the scan type to active */
12087 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012089 else
12090 {
12091 /*Set the scan type to default type, in this case it is ACTIVE*/
12092 scanRequest.scanType = pScanInfo->scan_mode;
12093 }
12094 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12095 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012096
12097 /* set BSSType to default type */
12098 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12099
12100 /*TODO: scan the requested channels only*/
12101
12102 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012103 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012105 hddLog(VOS_TRACE_LEVEL_WARN,
12106 "No of Scan Channels exceeded limit: %d", request->n_channels);
12107 request->n_channels = MAX_CHANNEL;
12108 }
12109
12110 hddLog(VOS_TRACE_LEVEL_INFO,
12111 "No of Scan Channels: %d", request->n_channels);
12112
12113
12114 if( request->n_channels )
12115 {
12116 char chList [(request->n_channels*5)+1];
12117 int len;
12118 channelList = vos_mem_malloc( request->n_channels );
12119 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012120 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012121 hddLog(VOS_TRACE_LEVEL_ERROR,
12122 "%s: memory alloc failed channelList", __func__);
12123 status = -ENOMEM;
12124 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012125 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012126
12127 for( i = 0, len = 0; i < request->n_channels ; i++ )
12128 {
12129 channelList[i] = request->channels[i]->hw_value;
12130 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12131 }
12132
Nirav Shah20ac06f2013-12-12 18:14:06 +053012133 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012134 "Channel-List: %s ", chList);
12135 }
c_hpothu53512302014-04-15 18:49:53 +053012136
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012137 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
12138 scanRequest.ChannelInfo.ChannelList = channelList;
12139
12140 /* set requestType to full scan */
12141 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
12142
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012143 /* if there is back to back scan happening in driver with in
12144 * nDeferScanTimeInterval interval driver should defer new scan request
12145 * and should provide last cached scan results instead of new channel list.
12146 * This rule is not applicable if scan is p2p scan.
12147 * This condition will work only in case when last request no of channels
12148 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053012149 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053012150 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012151 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012152
Sushant Kaushik86592172015-04-27 16:35:03 +053012153 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
12154 /* if wps ie is NULL , then only defer scan */
12155 if ( pWpsIe == NULL &&
12156 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053012157 {
12158 if ( pScanInfo->last_scan_timestamp !=0 &&
12159 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
12160 {
12161 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
12162 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
12163 vos_mem_compare(pScanInfo->last_scan_channelList,
12164 channelList, pScanInfo->last_scan_numChannels))
12165 {
12166 hddLog(VOS_TRACE_LEVEL_WARN,
12167 " New and old station scan time differ is less then %u",
12168 pHddCtx->cfg_ini->nDeferScanTimeInterval);
12169
12170 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012171 pAdapter);
12172
Agarwal Ashish57e84372014-12-05 18:26:53 +053012173 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012174 "Return old cached scan as all channels and no of channels are same");
12175
Agarwal Ashish57e84372014-12-05 18:26:53 +053012176 if (0 > ret)
12177 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012178
Agarwal Ashish57e84372014-12-05 18:26:53 +053012179 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012180
12181 status = eHAL_STATUS_SUCCESS;
12182 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053012183 }
12184 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012185 }
12186
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012187 /* Flush the scan results(only p2p beacons) for STA scan and P2P
12188 * search (Flush on both full scan and social scan but not on single
12189 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
12190 */
12191
12192 /* Supplicant does single channel scan after 8-way handshake
12193 * and in that case driver shoudnt flush scan results. If
12194 * driver flushes the scan results here and unfortunately if
12195 * the AP doesnt respond to our probe req then association
12196 * fails which is not desired
12197 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012198 if ((request->n_ssids == 1)
12199 && (request->ssids != NULL)
12200 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
12201 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012202
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012203 if( is_p2p_scan ||
12204 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012205 {
12206 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
12207 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
12208 pAdapter->sessionId );
12209 }
12210
12211 if( request->ie_len )
12212 {
12213 /* save this for future association (join requires this) */
12214 /*TODO: Array needs to be converted to dynamic allocation,
12215 * as multiple ie.s can be sent in cfg80211_scan_request structure
12216 * CR 597966
12217 */
12218 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
12219 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
12220 pScanInfo->scanAddIE.length = request->ie_len;
12221
12222 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12223 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12224 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012226 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012228 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
12229 memcpy( pwextBuf->roamProfile.addIEScan,
12230 request->ie, request->ie_len);
12231 }
12232 else
12233 {
12234 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
12235 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 }
12237
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012238 }
12239 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
12240 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
12241
12242 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
12243 request->ie_len);
12244 if (pP2pIe != NULL)
12245 {
12246#ifdef WLAN_FEATURE_P2P_DEBUG
12247 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
12248 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
12249 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053012250 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012251 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
12252 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
12253 "Go nego completed to Connection is started");
12254 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
12255 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053012256 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012257 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
12258 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012260 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
12261 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
12262 "Disconnected state to Connection is started");
12263 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
12264 "for 4way Handshake");
12265 }
12266#endif
12267
12268 /* no_cck will be set during p2p find to disable 11b rates */
12269 if(TRUE == request->no_cck)
12270 {
12271 hddLog(VOS_TRACE_LEVEL_INFO,
12272 "%s: This is a P2P Search", __func__);
12273 scanRequest.p2pSearch = 1;
12274
12275 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053012276 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012277 /* set requestType to P2P Discovery */
12278 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
12279 }
12280
12281 /*
12282 Skip Dfs Channel in case of P2P Search
12283 if it is set in ini file
12284 */
12285 if(cfg_param->skipDfsChnlInP2pSearch)
12286 {
12287 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053012288 }
12289 else
12290 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012291 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053012292 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012293
Agarwal Ashish4f616132013-12-30 23:32:50 +053012294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 }
12296 }
12297
12298 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
12299
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012300#ifdef FEATURE_WLAN_TDLS
12301 /* if tdls disagree scan right now, return immediately.
12302 tdls will schedule the scan when scan is allowed. (return SUCCESS)
12303 or will reject the scan if any TDLS is in progress. (return -EBUSY)
12304 */
12305 status = wlan_hdd_tdls_scan_callback (pAdapter,
12306 wiphy,
12307#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12308 dev,
12309#endif
12310 request);
12311 if(status <= 0)
12312 {
12313 if(!status)
12314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
12315 "scan rejected %d", __func__, status);
12316 else
12317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
12318 __func__, status);
12319
12320 return status;
12321 }
12322#endif
12323
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012324 /* acquire the wakelock to avoid the apps suspend during the scan. To
12325 * address the following issues.
12326 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
12327 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
12328 * for long time, this result in apps running at full power for long time.
12329 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
12330 * be stuck in full power because of resume BMPS
12331 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012332 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012333
Nirav Shah20ac06f2013-12-12 18:14:06 +053012334 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12335 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012336 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
12337 scanRequest.requestType, scanRequest.scanType,
12338 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053012339 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
12340
Siddharth Bhal76972212014-10-15 16:22:51 +053012341 if (pHddCtx->spoofMacAddr.isEnabled)
12342 {
12343 hddLog(VOS_TRACE_LEVEL_INFO,
12344 "%s: MAC Spoofing enabled for current scan", __func__);
12345 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
12346 * to fill TxBds for probe request during current scan
12347 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012348 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053012349 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012350
12351 if(status != VOS_STATUS_SUCCESS)
12352 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012353 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012354 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053012355#ifdef FEATURE_WLAN_TDLS
12356 wlan_hdd_tdls_scan_done_callback(pAdapter);
12357#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012358 goto free_mem;
12359 }
Siddharth Bhal76972212014-10-15 16:22:51 +053012360 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012361 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070012362 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 pAdapter->sessionId, &scanRequest, &scanId,
12364 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070012365
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 if (eHAL_STATUS_SUCCESS != status)
12367 {
12368 hddLog(VOS_TRACE_LEVEL_ERROR,
12369 "%s: sme_ScanRequest returned error %d", __func__, status);
12370 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012371 if(eHAL_STATUS_RESOURCES == status)
12372 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
12374 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012375 status = -EBUSY;
12376 } else {
12377 status = -EIO;
12378 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012379 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012380
12381#ifdef FEATURE_WLAN_TDLS
12382 wlan_hdd_tdls_scan_done_callback(pAdapter);
12383#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 goto free_mem;
12385 }
12386
12387 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012388 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 pAdapter->request = request;
12390 pScanInfo->scanId = scanId;
12391
12392 complete(&pScanInfo->scan_req_completion_event);
12393
12394free_mem:
12395 if( scanRequest.SSIDs.SSIDList )
12396 {
12397 vos_mem_free(scanRequest.SSIDs.SSIDList);
12398 }
12399
12400 if( channelList )
12401 vos_mem_free( channelList );
12402
12403 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012404 return status;
12405}
12406
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012407int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
12408#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12409 struct net_device *dev,
12410#endif
12411 struct cfg80211_scan_request *request)
12412{
12413 int ret;
12414
12415 vos_ssr_protect(__func__);
12416 ret = __wlan_hdd_cfg80211_scan(wiphy,
12417#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12418 dev,
12419#endif
12420 request);
12421 vos_ssr_unprotect(__func__);
12422
12423 return ret;
12424}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012425
12426void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
12427{
12428 v_U8_t iniDot11Mode =
12429 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
12430 eHddDot11Mode hddDot11Mode = iniDot11Mode;
12431
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012432 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
12433 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012434 switch ( iniDot11Mode )
12435 {
12436 case eHDD_DOT11_MODE_AUTO:
12437 case eHDD_DOT11_MODE_11ac:
12438 case eHDD_DOT11_MODE_11ac_ONLY:
12439#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053012440 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
12441 sme_IsFeatureSupportedByFW(DOT11AC) )
12442 hddDot11Mode = eHDD_DOT11_MODE_11ac;
12443 else
12444 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012445#else
12446 hddDot11Mode = eHDD_DOT11_MODE_11n;
12447#endif
12448 break;
12449 case eHDD_DOT11_MODE_11n:
12450 case eHDD_DOT11_MODE_11n_ONLY:
12451 hddDot11Mode = eHDD_DOT11_MODE_11n;
12452 break;
12453 default:
12454 hddDot11Mode = iniDot11Mode;
12455 break;
12456 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012457#ifdef WLAN_FEATURE_AP_HT40_24G
12458 if (operationChannel > SIR_11B_CHANNEL_END)
12459#endif
12460 {
12461 /* This call decides required channel bonding mode */
12462 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012463 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
12464 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012465 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012466}
12467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468/*
12469 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012470 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012473 const u8 *ssid, size_t ssid_len, const u8 *bssid,
12474 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070012475{
12476 int status = 0;
12477 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080012478 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 v_U32_t roamId;
12480 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012482 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012483
12484 ENTER();
12485
12486 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080012487 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12488
12489 status = wlan_hdd_validate_context(pHddCtx);
12490 if (status)
12491 {
Yue Mae36e3552014-03-05 17:06:20 -080012492 return status;
12493 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
12496 {
12497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
12498 return -EINVAL;
12499 }
12500
12501 pRoamProfile = &pWextState->roamProfile;
12502
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012503 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012505 hdd_station_ctx_t *pHddStaCtx;
12506 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012507
Siddharth Bhalda0d1622015-04-24 15:47:49 +053012508 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
12509
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012510 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
12512 {
12513 /*QoS not enabled in cfg file*/
12514 pRoamProfile->uapsd_mask = 0;
12515 }
12516 else
12517 {
12518 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012519 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070012520 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
12521 }
12522
12523 pRoamProfile->SSIDs.numOfSSIDs = 1;
12524 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
12525 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012526 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
12528 ssid, ssid_len);
12529
12530 if (bssid)
12531 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012532 pValidBssid = bssid;
12533 }
12534 else if (bssid_hint)
12535 {
12536 pValidBssid = bssid_hint;
12537 }
12538 if (pValidBssid)
12539 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012541 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012543 /* Save BSSID in seperate variable as well, as RoamProfile
12544 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 case of join failure we should send valid BSSID to supplicant
12546 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012547 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 WNI_CFG_BSSID_LEN);
12549 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012550 else
12551 {
12552 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12553 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012554
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012555 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12556 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12558 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012559 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 /*set gen ie*/
12561 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12562 /*set auth*/
12563 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12564 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012565#ifdef FEATURE_WLAN_WAPI
12566 if (pAdapter->wapi_info.nWapiMode)
12567 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012568 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 switch (pAdapter->wapi_info.wapiAuthMode)
12570 {
12571 case WAPI_AUTH_MODE_PSK:
12572 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012573 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 pAdapter->wapi_info.wapiAuthMode);
12575 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12576 break;
12577 }
12578 case WAPI_AUTH_MODE_CERT:
12579 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012580 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 pAdapter->wapi_info.wapiAuthMode);
12582 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12583 break;
12584 }
12585 } // End of switch
12586 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12587 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12588 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012589 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012590 pRoamProfile->AuthType.numEntries = 1;
12591 pRoamProfile->EncryptionType.numEntries = 1;
12592 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12593 pRoamProfile->mcEncryptionType.numEntries = 1;
12594 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12595 }
12596 }
12597#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012598#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012599 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012600 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12601 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12602 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012603 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12604 sizeof (tSirGtkOffloadParams));
12605 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012606 }
12607#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 pRoamProfile->csrPersona = pAdapter->device_mode;
12609
Jeff Johnson32d95a32012-09-10 13:15:23 -070012610 if( operatingChannel )
12611 {
12612 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12613 pRoamProfile->ChannelInfo.numOfChannels = 1;
12614 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012615 else
12616 {
12617 pRoamProfile->ChannelInfo.ChannelList = NULL;
12618 pRoamProfile->ChannelInfo.numOfChannels = 0;
12619 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012620 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12621 {
12622 hdd_select_cbmode(pAdapter,operatingChannel);
12623 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012624
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012625 /*
12626 * Change conn_state to connecting before sme_RoamConnect(),
12627 * because sme_RoamConnect() has a direct path to call
12628 * hdd_smeRoamCallback(), which will change the conn_state
12629 * If direct path, conn_state will be accordingly changed
12630 * to NotConnected or Associated by either
12631 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12632 * in sme_RoamCallback()
12633 * if sme_RomConnect is to be queued,
12634 * Connecting state will remain until it is completed.
12635 * If connection state is not changed,
12636 * connection state will remain in eConnectionState_NotConnected state.
12637 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12638 * if conn state is eConnectionState_NotConnected.
12639 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12640 * informed of connect result indication which is an issue.
12641 */
12642
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012643 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12644 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012645 {
12646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012647 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012648 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12649 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012650 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012651 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 pAdapter->sessionId, pRoamProfile, &roamId);
12653
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012654 if ((eHAL_STATUS_SUCCESS != status) &&
12655 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12656 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012657
12658 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012659 hddLog(VOS_TRACE_LEVEL_ERROR,
12660 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12661 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012662 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012663 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012664 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012665 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012666
12667 pRoamProfile->ChannelInfo.ChannelList = NULL;
12668 pRoamProfile->ChannelInfo.numOfChannels = 0;
12669
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 }
12671 else
12672 {
12673 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12674 return -EINVAL;
12675 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012676 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 return status;
12678}
12679
12680/*
12681 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12682 * This function is used to set the authentication type (OPEN/SHARED).
12683 *
12684 */
12685static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12686 enum nl80211_auth_type auth_type)
12687{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12690
12691 ENTER();
12692
12693 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012697 hddLog(VOS_TRACE_LEVEL_INFO,
12698 "%s: set authentication type to AUTOSWITCH", __func__);
12699 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12700 break;
12701
12702 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012703#ifdef WLAN_FEATURE_VOWIFI_11R
12704 case NL80211_AUTHTYPE_FT:
12705#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012706 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 "%s: set authentication type to OPEN", __func__);
12708 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12709 break;
12710
12711 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012712 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012713 "%s: set authentication type to SHARED", __func__);
12714 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12715 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012716#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012718 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 "%s: set authentication type to CCKM WPA", __func__);
12720 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12721 break;
12722#endif
12723
12724
12725 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012726 hddLog(VOS_TRACE_LEVEL_ERROR,
12727 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 auth_type);
12729 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12730 return -EINVAL;
12731 }
12732
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012733 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 pHddStaCtx->conn_info.authType;
12735 return 0;
12736}
12737
12738/*
12739 * FUNCTION: wlan_hdd_set_akm_suite
12740 * This function is used to set the key mgmt type(PSK/8021x).
12741 *
12742 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 u32 key_mgmt
12745 )
12746{
12747 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12748 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012749 /* Should be in ieee802_11_defs.h */
12750#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12751#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012752 /*set key mgmt type*/
12753 switch(key_mgmt)
12754 {
12755 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012756 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012757#ifdef WLAN_FEATURE_VOWIFI_11R
12758 case WLAN_AKM_SUITE_FT_PSK:
12759#endif
12760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 __func__);
12762 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12763 break;
12764
12765 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012766 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012767#ifdef WLAN_FEATURE_VOWIFI_11R
12768 case WLAN_AKM_SUITE_FT_8021X:
12769#endif
12770 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012771 __func__);
12772 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12773 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012774#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012775#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12776#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12777 case WLAN_AKM_SUITE_CCKM:
12778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12779 __func__);
12780 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12781 break;
12782#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012783#ifndef WLAN_AKM_SUITE_OSEN
12784#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12785 case WLAN_AKM_SUITE_OSEN:
12786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12787 __func__);
12788 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12789 break;
12790#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012791
12792 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012794 __func__, key_mgmt);
12795 return -EINVAL;
12796
12797 }
12798 return 0;
12799}
12800
12801/*
12802 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012803 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 * (NONE/WEP40/WEP104/TKIP/CCMP).
12805 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012806static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12807 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 bool ucast
12809 )
12810{
12811 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012812 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012813 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12814
12815 ENTER();
12816
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012817 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 __func__, cipher);
12821 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12822 }
12823 else
12824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012825
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012827 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 {
12829 case IW_AUTH_CIPHER_NONE:
12830 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12831 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012832
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012834 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012835 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012836
Jeff Johnson295189b2012-06-20 16:38:30 -070012837 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012838 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 case WLAN_CIPHER_SUITE_TKIP:
12842 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12843 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012844
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 case WLAN_CIPHER_SUITE_CCMP:
12846 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12847 break;
12848#ifdef FEATURE_WLAN_WAPI
12849 case WLAN_CIPHER_SUITE_SMS4:
12850 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12851 break;
12852#endif
12853
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012854#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 case WLAN_CIPHER_SUITE_KRK:
12856 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12857 break;
12858#endif
12859 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 __func__, cipher);
12862 return -EOPNOTSUPP;
12863 }
12864 }
12865
12866 if (ucast)
12867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012868 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012869 __func__, encryptionType);
12870 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12871 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012872 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012873 encryptionType;
12874 }
12875 else
12876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 __func__, encryptionType);
12879 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12880 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12881 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12882 }
12883
12884 return 0;
12885}
12886
12887
12888/*
12889 * FUNCTION: wlan_hdd_cfg80211_set_ie
12890 * This function is used to parse WPA/RSN IE's.
12891 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12894 const u8 *ie,
12895#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012896 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012897#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012898 size_t ie_len
12899 )
12900{
12901 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012902#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12903 const u8 *genie = ie;
12904#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012906#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 v_U16_t remLen = ie_len;
12908#ifdef FEATURE_WLAN_WAPI
12909 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12910 u16 *tmp;
12911 v_U16_t akmsuiteCount;
12912 int *akmlist;
12913#endif
12914 ENTER();
12915
12916 /* clear previous assocAddIE */
12917 pWextState->assocAddIE.length = 0;
12918 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012919 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012920
12921 while (remLen >= 2)
12922 {
12923 v_U16_t eLen = 0;
12924 v_U8_t elementId;
12925 elementId = *genie++;
12926 eLen = *genie++;
12927 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012928
Arif Hussain6d2a3322013-11-17 19:50:10 -080012929 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012931
12932 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012933 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012934 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012935 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 -070012936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012937 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 "%s: Invalid WPA IE", __func__);
12939 return -EINVAL;
12940 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012941 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012942 {
12943 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012944 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012946
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012947 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012949 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12950 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 VOS_ASSERT(0);
12952 return -ENOMEM;
12953 }
12954 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12955 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12956 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012957
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12959 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12960 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12961 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012962 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12963 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012964 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12965 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12966 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12967 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12968 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12969 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012970 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012971 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012972 {
12973 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012974 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012975 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012976
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012977 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012978 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012979 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12980 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012981 VOS_ASSERT(0);
12982 return -ENOMEM;
12983 }
12984 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12985 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12986 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012987
Jeff Johnson295189b2012-06-20 16:38:30 -070012988 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12989 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12990 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012991#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012992 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12993 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 /*Consider WFD IE, only for P2P Client */
12995 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12996 {
12997 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012998 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013000
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013001 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013003 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13004 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013005 VOS_ASSERT(0);
13006 return -ENOMEM;
13007 }
13008 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13009 // WPS IE + P2P IE + WFD IE
13010 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13011 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013012
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13014 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13015 }
13016#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013017 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013018 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013019 HS20_OUI_TYPE_SIZE)) )
13020 {
13021 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013022 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013023 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013024
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013025 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013026 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013027 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13028 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013029 VOS_ASSERT(0);
13030 return -ENOMEM;
13031 }
13032 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13033 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013034
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013035 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13036 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13037 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013038 /* Appending OSEN Information Element in Assiciation Request */
13039 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13040 OSEN_OUI_TYPE_SIZE)) )
13041 {
13042 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13043 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13044 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013045
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013046 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013047 {
13048 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13049 "Need bigger buffer space");
13050 VOS_ASSERT(0);
13051 return -ENOMEM;
13052 }
13053 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13054 pWextState->assocAddIE.length += eLen + 2;
13055
13056 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13057 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13058 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13059 }
13060
Abhishek Singh4322e622015-06-10 15:42:54 +053013061 /* Update only for WPA IE */
13062 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13063 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013064
13065 /* populating as ADDIE in beacon frames */
13066 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013067 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013068 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13069 {
13070 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13071 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13072 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13073 {
13074 hddLog(LOGE,
13075 "Coldn't pass "
13076 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13077 }
13078 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13079 else
13080 hddLog(LOGE,
13081 "Could not pass on "
13082 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13083
13084 /* IBSS mode doesn't contain params->proberesp_ies still
13085 beaconIE's need to be populated in probe response frames */
13086 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13087 {
13088 u16 rem_probe_resp_ie_len = eLen + 2;
13089 u8 probe_rsp_ie_len[3] = {0};
13090 u8 counter = 0;
13091
13092 /* Check Probe Resp Length if it is greater then 255 then
13093 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13094 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13095 not able Store More then 255 bytes into One Variable */
13096
13097 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13098 {
13099 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13100 {
13101 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13102 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13103 }
13104 else
13105 {
13106 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13107 rem_probe_resp_ie_len = 0;
13108 }
13109 }
13110
13111 rem_probe_resp_ie_len = 0;
13112
13113 if (probe_rsp_ie_len[0] > 0)
13114 {
13115 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13116 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13117 (tANI_U8*)(genie - 2),
13118 probe_rsp_ie_len[0], NULL,
13119 eANI_BOOLEAN_FALSE)
13120 == eHAL_STATUS_FAILURE)
13121 {
13122 hddLog(LOGE,
13123 "Could not pass"
13124 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13125 }
13126 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13127 }
13128
13129 if (probe_rsp_ie_len[1] > 0)
13130 {
13131 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13132 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13133 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13134 probe_rsp_ie_len[1], NULL,
13135 eANI_BOOLEAN_FALSE)
13136 == eHAL_STATUS_FAILURE)
13137 {
13138 hddLog(LOGE,
13139 "Could not pass"
13140 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
13141 }
13142 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
13143 }
13144
13145 if (probe_rsp_ie_len[2] > 0)
13146 {
13147 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13148 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
13149 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13150 probe_rsp_ie_len[2], NULL,
13151 eANI_BOOLEAN_FALSE)
13152 == eHAL_STATUS_FAILURE)
13153 {
13154 hddLog(LOGE,
13155 "Could not pass"
13156 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
13157 }
13158 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
13159 }
13160
13161 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13162 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
13163 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13164 {
13165 hddLog(LOGE,
13166 "Could not pass"
13167 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
13168 }
13169 }
13170 else
13171 {
13172 // Reset WNI_CFG_PROBE_RSP Flags
13173 wlan_hdd_reset_prob_rspies(pAdapter);
13174
13175 hddLog(VOS_TRACE_LEVEL_INFO,
13176 "%s: No Probe Response IE received in set beacon",
13177 __func__);
13178 }
13179 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 break;
13181 case DOT11F_EID_RSN:
13182 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
13183 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13184 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
13185 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
13186 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
13187 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053013188
13189 /* Appending Extended Capabilities with Interworking bit set
13190 * in Assoc Req.
13191 *
13192 * In assoc req this EXT Cap will only be taken into account if
13193 * interworkingService bit is set to 1. Currently
13194 * driver is only interested in interworkingService capability
13195 * from supplicant. If in future any other EXT Cap info is
13196 * required from supplicat, it needs to be handled while
13197 * sending Assoc Req in LIM.
13198 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013199 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013200 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013201 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013202 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013203 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013205 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013206 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013207 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13208 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013209 VOS_ASSERT(0);
13210 return -ENOMEM;
13211 }
13212 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13213 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013215 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13216 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13217 break;
13218 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013219#ifdef FEATURE_WLAN_WAPI
13220 case WLAN_EID_WAPI:
13221 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013222 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013223 pAdapter->wapi_info.nWapiMode);
13224 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 akmsuiteCount = WPA_GET_LE16(tmp);
13227 tmp = tmp + 1;
13228 akmlist = (int *)(tmp);
13229 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
13230 {
13231 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
13232 }
13233 else
13234 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013235 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 VOS_ASSERT(0);
13237 return -EINVAL;
13238 }
13239
13240 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
13241 {
13242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013243 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013249 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013250 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
13251 }
13252 break;
13253#endif
13254 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013255 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013256 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013257 /* when Unknown IE is received we should break and continue
13258 * to the next IE in the buffer instead we were returning
13259 * so changing this to break */
13260 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013261 }
13262 genie += eLen;
13263 remLen -= eLen;
13264 }
13265 EXIT();
13266 return 0;
13267}
13268
13269/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053013270 * FUNCTION: hdd_isWPAIEPresent
13271 * Parse the received IE to find the WPA IE
13272 *
13273 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013274static bool hdd_isWPAIEPresent(
13275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13276 const u8 *ie,
13277#else
13278 u8 *ie,
13279#endif
13280 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053013281{
13282 v_U8_t eLen = 0;
13283 v_U16_t remLen = ie_len;
13284 v_U8_t elementId = 0;
13285
13286 while (remLen >= 2)
13287 {
13288 elementId = *ie++;
13289 eLen = *ie++;
13290 remLen -= 2;
13291 if (eLen > remLen)
13292 {
13293 hddLog(VOS_TRACE_LEVEL_ERROR,
13294 "%s: IE length is wrong %d", __func__, eLen);
13295 return FALSE;
13296 }
13297 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
13298 {
13299 /* OUI - 0x00 0X50 0XF2
13300 WPA Information Element - 0x01
13301 WPA version - 0x01*/
13302 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
13303 return TRUE;
13304 }
13305 ie += eLen;
13306 remLen -= eLen;
13307 }
13308 return FALSE;
13309}
13310
13311/*
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013313 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013314 * parameters during connect operation.
13315 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013316int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013317 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013318 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013319{
13320 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013321 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 ENTER();
13323
13324 /*set wpa version*/
13325 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
13326
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013327 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013328 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053013329 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 {
13331 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13332 }
13333 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
13334 {
13335 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13336 }
13337 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013338
13339 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 pWextState->wpaVersion);
13341
13342 /*set authentication type*/
13343 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
13344
13345 if (0 > status)
13346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013347 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 "%s: failed to set authentication type ", __func__);
13349 return status;
13350 }
13351
13352 /*set key mgmt type*/
13353 if (req->crypto.n_akm_suites)
13354 {
13355 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
13356 if (0 > status)
13357 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 __func__);
13360 return status;
13361 }
13362 }
13363
13364 /*set pairwise cipher type*/
13365 if (req->crypto.n_ciphers_pairwise)
13366 {
13367 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
13368 req->crypto.ciphers_pairwise[0], true);
13369 if (0 > status)
13370 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013371 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 "%s: failed to set unicast cipher type", __func__);
13373 return status;
13374 }
13375 }
13376 else
13377 {
13378 /*Reset previous cipher suite to none*/
13379 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
13380 if (0 > status)
13381 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013382 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 "%s: failed to set unicast cipher type", __func__);
13384 return status;
13385 }
13386 }
13387
13388 /*set group cipher type*/
13389 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
13390 false);
13391
13392 if (0 > status)
13393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 __func__);
13396 return status;
13397 }
13398
Chet Lanctot186b5732013-03-18 10:26:30 -070013399#ifdef WLAN_FEATURE_11W
13400 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
13401#endif
13402
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
13404 if (req->ie_len)
13405 {
13406 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
13407 if ( 0 > status)
13408 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 __func__);
13411 return status;
13412 }
13413 }
13414
13415 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013416 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 {
13418 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
13419 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
13420 )
13421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013422 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
13424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 __func__);
13427 return -EOPNOTSUPP;
13428 }
13429 else
13430 {
13431 u8 key_len = req->key_len;
13432 u8 key_idx = req->key_idx;
13433
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013434 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 && (CSR_MAX_NUM_KEY > key_idx)
13436 )
13437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438 hddLog(VOS_TRACE_LEVEL_INFO,
13439 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 __func__, key_idx, key_len);
13441 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013442 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013444 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 (u8)key_len;
13446 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
13447 }
13448 }
13449 }
13450 }
13451
13452 return status;
13453}
13454
13455/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013456 * FUNCTION: wlan_hdd_try_disconnect
13457 * This function is used to disconnect from previous
13458 * connection
13459 */
13460static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
13461{
13462 long ret = 0;
13463 hdd_station_ctx_t *pHddStaCtx;
13464 eMib_dot11DesiredBssType connectedBssType;
13465
13466 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13467
13468 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
13469
13470 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
13471 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
13472 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
13473 {
13474 /* Issue disconnect to CSR */
13475 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13476 if( eHAL_STATUS_SUCCESS ==
13477 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13478 pAdapter->sessionId,
13479 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
13480 {
13481 ret = wait_for_completion_interruptible_timeout(
13482 &pAdapter->disconnect_comp_var,
13483 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13484 if (0 >= ret)
13485 {
13486 hddLog(LOGE, FL("Failed to receive disconnect event"));
13487 return -EALREADY;
13488 }
13489 }
13490 }
13491 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
13492 {
13493 ret = wait_for_completion_interruptible_timeout(
13494 &pAdapter->disconnect_comp_var,
13495 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13496 if (0 >= ret)
13497 {
13498 hddLog(LOGE, FL("Failed to receive disconnect event"));
13499 return -EALREADY;
13500 }
13501 }
13502
13503 return 0;
13504}
13505
13506/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053013507 * FUNCTION: __wlan_hdd_cfg80211_connect
13508 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013510static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013511 struct net_device *ndev,
13512 struct cfg80211_connect_params *req
13513 )
13514{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013515 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053013518 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013519
13520 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013521
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013522 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13523 TRACE_CODE_HDD_CFG80211_CONNECT,
13524 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013525 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013526 "%s: device_mode = %s (%d)", __func__,
13527 hdd_device_modetoString(pAdapter->device_mode),
13528 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013529
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013530 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013531 if (!pHddCtx)
13532 {
13533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13534 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013535 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013536 }
13537
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013538 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013539 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013541 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 }
13543
Agarwal Ashish51325b52014-06-16 16:50:49 +053013544 if (vos_max_concurrent_connections_reached()) {
13545 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13546 return -ECONNREFUSED;
13547 }
13548
Jeff Johnson295189b2012-06-20 16:38:30 -070013549#ifdef WLAN_BTAMP_FEATURE
13550 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013553 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013555 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 }
13557#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013558
13559 //If Device Mode is Station Concurrent Sessions Exit BMps
13560 //P2P Mode will be taken care in Open/close adapter
13561 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013562 (vos_concurrent_open_sessions_running())) {
13563 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13564 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013565 }
13566
13567 /*Try disconnecting if already in connected state*/
13568 status = wlan_hdd_try_disconnect(pAdapter);
13569 if ( 0 > status)
13570 {
13571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13572 " connection"));
13573 return -EALREADY;
13574 }
13575
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013577 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013578
13579 if ( 0 > status)
13580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013582 __func__);
13583 return status;
13584 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013585 if ( req->channel )
13586 {
13587 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13588 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013589 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070013590 req->channel->hw_value);
13591 }
13592 else
13593 {
13594 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013595 req->ssid_len, req->bssid,
13596 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013598
Sushant Kaushikd7083982015-03-18 14:33:24 +053013599 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 {
13601 //ReEnable BMPS if disabled
13602 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13603 (NULL != pHddCtx))
13604 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013605 if (pHddCtx->hdd_wlan_suspended)
13606 {
13607 hdd_set_pwrparams(pHddCtx);
13608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 //ReEnable Bmps and Imps back
13610 hdd_enable_bmps_imps(pHddCtx);
13611 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 return status;
13614 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013615 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 EXIT();
13617 return status;
13618}
13619
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013620static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13621 struct net_device *ndev,
13622 struct cfg80211_connect_params *req)
13623{
13624 int ret;
13625 vos_ssr_protect(__func__);
13626 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13627 vos_ssr_unprotect(__func__);
13628
13629 return ret;
13630}
Jeff Johnson295189b2012-06-20 16:38:30 -070013631
13632/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013633 * FUNCTION: wlan_hdd_disconnect
13634 * This function is used to issue a disconnect request to SME
13635 */
13636int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13637{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013638 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013639 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013640 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013641 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013643 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013644
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013646 if (0 != status)
13647 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013648 return status;
13649 }
13650
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013651 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13652 {
13653 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13654 pAdapter->sessionId);
13655 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013656 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013657
Agarwal Ashish47d18112014-08-04 19:55:07 +053013658 /* Need to apply spin lock before decreasing active sessions
13659 * as there can be chance for double decrement if context switch
13660 * Calls hdd_DisConnectHandler.
13661 */
13662
13663 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013664 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13665 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013666 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13667 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013668 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13669 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013670
Abhishek Singhf4669da2014-05-26 15:07:49 +053013671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013672 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13673
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013674 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013675
Mihir Shete182a0b22014-08-18 16:08:48 +053013676 /*
13677 * stop tx queues before deleting STA/BSS context from the firmware.
13678 * tx has to be disabled because the firmware can get busy dropping
13679 * the tx frames after BSS/STA has been deleted and will not send
13680 * back a response resulting in WDI timeout
13681 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013682 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013683 netif_tx_disable(pAdapter->dev);
13684 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013685
Mihir Shete182a0b22014-08-18 16:08:48 +053013686 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013687 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13688 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013689 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13690 {
13691 hddLog(VOS_TRACE_LEVEL_INFO,
13692 FL("status = %d, already disconnected"),
13693 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013694
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013695 }
13696 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013697 {
13698 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013699 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013700 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013701 result = -EINVAL;
13702 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013703 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013704 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013705 &pAdapter->disconnect_comp_var,
13706 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013707 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013708 {
13709 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013710 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013711 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013712 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013713 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013714 {
13715 hddLog(VOS_TRACE_LEVEL_ERROR,
13716 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013717 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013718 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013719disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13721 FL("Set HDD connState to eConnectionState_NotConnected"));
13722 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13723
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013724 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013725 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013726}
13727
13728
13729/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013730 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 * This function is used to issue a disconnect request to SME
13732 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013733static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 struct net_device *dev,
13735 u16 reason
13736 )
13737{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013739 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013740 tCsrRoamProfile *pRoamProfile;
13741 hdd_station_ctx_t *pHddStaCtx;
13742 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013743#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013744 tANI_U8 staIdx;
13745#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013748
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013749 if (!pAdapter) {
13750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13751 return -EINVAL;
13752 }
13753
13754 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13755 if (!pHddStaCtx) {
13756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13757 return -EINVAL;
13758 }
13759
13760 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13761 status = wlan_hdd_validate_context(pHddCtx);
13762 if (0 != status)
13763 {
13764 return status;
13765 }
13766
13767 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13768
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013769 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13770 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13771 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13773 __func__, hdd_device_modetoString(pAdapter->device_mode),
13774 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013775
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13777 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013778
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 if (NULL != pRoamProfile)
13780 {
13781 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013782 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13783 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013785 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013787 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 switch(reason)
13789 {
13790 case WLAN_REASON_MIC_FAILURE:
13791 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13792 break;
13793
13794 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13795 case WLAN_REASON_DISASSOC_AP_BUSY:
13796 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13797 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13798 break;
13799
13800 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13801 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013802 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13804 break;
13805
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 default:
13807 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13808 break;
13809 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013810 pScanInfo = &pHddCtx->scan_info;
13811 if (pScanInfo->mScanPending)
13812 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013813 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013814 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013815 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013816 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013817 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013818 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013819#ifdef FEATURE_WLAN_TDLS
13820 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013821 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013822 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013823 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13824 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013825 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013826 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013827 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013829 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013830 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013831 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013832 status = sme_DeleteTdlsPeerSta(
13833 WLAN_HDD_GET_HAL_CTX(pAdapter),
13834 pAdapter->sessionId,
13835 mac);
13836 if (status != eHAL_STATUS_SUCCESS) {
13837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13838 return -EPERM;
13839 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013840 }
13841 }
13842#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013843 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013844 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13845 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 {
13847 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013848 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013849 __func__, (int)status );
13850 return -EINVAL;
13851 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013853 else
13854 {
13855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13856 "called while in %d state", __func__,
13857 pHddStaCtx->conn_info.connState);
13858 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 }
13860 else
13861 {
13862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13863 }
13864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013865 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013866 return status;
13867}
13868
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013869static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13870 struct net_device *dev,
13871 u16 reason
13872 )
13873{
13874 int ret;
13875 vos_ssr_protect(__func__);
13876 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13877 vos_ssr_unprotect(__func__);
13878
13879 return ret;
13880}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013881
Jeff Johnson295189b2012-06-20 16:38:30 -070013882/*
13883 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013884 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 * settings in IBSS mode.
13886 */
13887static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013888 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 struct cfg80211_ibss_params *params
13890 )
13891{
13892 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013893 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13895 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 ENTER();
13898
13899 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013900 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013901
13902 if (params->ie_len && ( NULL != params->ie) )
13903 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013904 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13905 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 {
13907 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13908 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13909 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013910 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013912 tDot11fIEWPA dot11WPAIE;
13913 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013914 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013915
Wilson Yang00256342013-10-10 23:13:38 -070013916 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013917 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13918 params->ie_len, DOT11F_EID_WPA);
13919 if ( NULL != ie )
13920 {
13921 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13922 // Unpack the WPA IE
13923 //Skip past the EID byte and length byte - and four byte WiFi OUI
13924 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13925 &ie[2+4],
13926 ie[1] - 4,
13927 &dot11WPAIE);
13928 /*Extract the multicast cipher, the encType for unicast
13929 cipher for wpa-none is none*/
13930 encryptionType =
13931 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13932 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013934
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13936
13937 if (0 > status)
13938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 __func__);
13941 return status;
13942 }
13943 }
13944
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013945 pWextState->roamProfile.AuthType.authType[0] =
13946 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13948
13949 if (params->privacy)
13950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013951 /* Security enabled IBSS, At this time there is no information available
13952 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013954 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013956 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 *enable privacy bit in beacons */
13958
13959 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13960 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013961 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13962 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013963 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13964 pWextState->roamProfile.EncryptionType.numEntries = 1;
13965 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013966 return status;
13967}
13968
13969/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013970 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013971 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013973static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 struct net_device *dev,
13975 struct cfg80211_ibss_params *params
13976 )
13977{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013978 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013979 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13980 tCsrRoamProfile *pRoamProfile;
13981 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013982 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13983 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013984 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013985
13986 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013987
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013988 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13989 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13990 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013991 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013992 "%s: device_mode = %s (%d)", __func__,
13993 hdd_device_modetoString(pAdapter->device_mode),
13994 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013995
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013996 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013997 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013999 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 }
14001
14002 if (NULL == pWextState)
14003 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014004 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 __func__);
14006 return -EIO;
14007 }
14008
Agarwal Ashish51325b52014-06-16 16:50:49 +053014009 if (vos_max_concurrent_connections_reached()) {
14010 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14011 return -ECONNREFUSED;
14012 }
14013
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014014 /*Try disconnecting if already in connected state*/
14015 status = wlan_hdd_try_disconnect(pAdapter);
14016 if ( 0 > status)
14017 {
14018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14019 " IBSS connection"));
14020 return -EALREADY;
14021 }
14022
Jeff Johnson295189b2012-06-20 16:38:30 -070014023 pRoamProfile = &pWextState->roamProfile;
14024
14025 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014027 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014028 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 return -EINVAL;
14030 }
14031
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014032 /* BSSID is provided by upper layers hence no need to AUTO generate */
14033 if (NULL != params->bssid) {
14034 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14035 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14036 hddLog (VOS_TRACE_LEVEL_ERROR,
14037 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14038 return -EIO;
14039 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014040 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014041 }
krunal sonie9002db2013-11-25 14:24:17 -080014042 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14043 {
14044 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14045 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14046 {
14047 hddLog (VOS_TRACE_LEVEL_ERROR,
14048 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14049 return -EIO;
14050 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014051
14052 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014053 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014054 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014055 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014056
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014058 if (NULL !=
14059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14060 params->chandef.chan)
14061#else
14062 params->channel)
14063#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014064 {
14065 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014066 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14067 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14068 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14069 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014070
14071 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014073 ieee80211_frequency_to_channel(
14074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14075 params->chandef.chan->center_freq);
14076#else
14077 params->channel->center_freq);
14078#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014079
14080 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14081 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14084 __func__);
14085 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014087
14088 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014090 if (channelNum == validChan[indx])
14091 {
14092 break;
14093 }
14094 }
14095 if (indx >= numChans)
14096 {
14097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 __func__, channelNum);
14099 return -EINVAL;
14100 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014101 /* Set the Operational Channel */
14102 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14103 channelNum);
14104 pRoamProfile->ChannelInfo.numOfChannels = 1;
14105 pHddStaCtx->conn_info.operationChannel = channelNum;
14106 pRoamProfile->ChannelInfo.ChannelList =
14107 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 }
14109
14110 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014111 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 if (status < 0)
14113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 __func__);
14116 return status;
14117 }
14118
14119 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014120 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014121 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014122 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014123
14124 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014127 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014128 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014129}
14130
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014131static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14132 struct net_device *dev,
14133 struct cfg80211_ibss_params *params
14134 )
14135{
14136 int ret = 0;
14137
14138 vos_ssr_protect(__func__);
14139 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
14140 vos_ssr_unprotect(__func__);
14141
14142 return ret;
14143}
14144
Jeff Johnson295189b2012-06-20 16:38:30 -070014145/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014146 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014149static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 struct net_device *dev
14151 )
14152{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014154 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14155 tCsrRoamProfile *pRoamProfile;
14156 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014157 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014158
14159 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014160
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14162 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
14163 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014164 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014165 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014166 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014167 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014168 }
14169
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
14171 hdd_device_modetoString(pAdapter->device_mode),
14172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 if (NULL == pWextState)
14174 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014175 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014176 __func__);
14177 return -EIO;
14178 }
14179
14180 pRoamProfile = &pWextState->roamProfile;
14181
14182 /* Issue disconnect only if interface type is set to IBSS */
14183 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
14184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014185 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070014186 __func__);
14187 return -EINVAL;
14188 }
14189
14190 /* Issue Disconnect request */
14191 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14192 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14193 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
14194
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014195 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014196 return 0;
14197}
14198
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014199static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
14200 struct net_device *dev
14201 )
14202{
14203 int ret = 0;
14204
14205 vos_ssr_protect(__func__);
14206 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
14207 vos_ssr_unprotect(__func__);
14208
14209 return ret;
14210}
14211
Jeff Johnson295189b2012-06-20 16:38:30 -070014212/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014213 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070014214 * This function is used to set the phy parameters
14215 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
14216 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014217static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014218 u32 changed)
14219{
14220 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14221 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014222 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014223
14224 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014225
14226 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014227 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
14228 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014229
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014230 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014231 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014232 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014233 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014234 }
14235
Jeff Johnson295189b2012-06-20 16:38:30 -070014236 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
14237 {
14238 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
14239 WNI_CFG_RTS_THRESHOLD_STAMAX :
14240 wiphy->rts_threshold;
14241
14242 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014243 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070014244 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014245 hddLog(VOS_TRACE_LEVEL_ERROR,
14246 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014247 __func__, rts_threshold);
14248 return -EINVAL;
14249 }
14250
14251 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
14252 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014253 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014255 hddLog(VOS_TRACE_LEVEL_ERROR,
14256 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014257 __func__, rts_threshold);
14258 return -EIO;
14259 }
14260
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014261 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 rts_threshold);
14263 }
14264
14265 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
14266 {
14267 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
14268 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
14269 wiphy->frag_threshold;
14270
14271 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014272 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014274 hddLog(VOS_TRACE_LEVEL_ERROR,
14275 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 frag_threshold);
14277 return -EINVAL;
14278 }
14279
14280 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
14281 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014284 hddLog(VOS_TRACE_LEVEL_ERROR,
14285 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014286 __func__, frag_threshold);
14287 return -EIO;
14288 }
14289
14290 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
14291 frag_threshold);
14292 }
14293
14294 if ((changed & WIPHY_PARAM_RETRY_SHORT)
14295 || (changed & WIPHY_PARAM_RETRY_LONG))
14296 {
14297 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
14298 wiphy->retry_short :
14299 wiphy->retry_long;
14300
14301 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
14302 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
14303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 __func__, retry_value);
14306 return -EINVAL;
14307 }
14308
14309 if (changed & WIPHY_PARAM_RETRY_SHORT)
14310 {
14311 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
14312 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014313 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014315 hddLog(VOS_TRACE_LEVEL_ERROR,
14316 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014317 __func__, retry_value);
14318 return -EIO;
14319 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014320 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014321 __func__, retry_value);
14322 }
14323 else if (changed & WIPHY_PARAM_RETRY_SHORT)
14324 {
14325 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
14326 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014327 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014329 hddLog(VOS_TRACE_LEVEL_ERROR,
14330 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 __func__, retry_value);
14332 return -EIO;
14333 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014334 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014335 __func__, retry_value);
14336 }
14337 }
14338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014339 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014340 return 0;
14341}
14342
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014343static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
14344 u32 changed)
14345{
14346 int ret;
14347
14348 vos_ssr_protect(__func__);
14349 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
14350 vos_ssr_unprotect(__func__);
14351
14352 return ret;
14353}
14354
Jeff Johnson295189b2012-06-20 16:38:30 -070014355/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014356 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 * This function is used to set the txpower
14358 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014359static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014360#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14361 struct wireless_dev *wdev,
14362#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014363#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014364 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014365#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014366 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014367#endif
14368 int dbm)
14369{
14370 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014371 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014372 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
14373 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014374 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014375
14376 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014377
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14379 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
14380 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014381 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014382 if (0 != status)
14383 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014384 return status;
14385 }
14386
14387 hHal = pHddCtx->hHal;
14388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
14390 dbm, ccmCfgSetCallback,
14391 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014393 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
14395 return -EIO;
14396 }
14397
14398 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
14399 dbm);
14400
14401 switch(type)
14402 {
14403 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
14404 /* Fall through */
14405 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
14406 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
14407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
14409 __func__);
14410 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 }
14412 break;
14413 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 __func__);
14416 return -EOPNOTSUPP;
14417 break;
14418 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
14420 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 return -EIO;
14422 }
14423
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014424 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 return 0;
14426}
14427
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014428static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
14429#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14430 struct wireless_dev *wdev,
14431#endif
14432#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14433 enum tx_power_setting type,
14434#else
14435 enum nl80211_tx_power_setting type,
14436#endif
14437 int dbm)
14438{
14439 int ret;
14440 vos_ssr_protect(__func__);
14441 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
14442#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14443 wdev,
14444#endif
14445#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14446 type,
14447#else
14448 type,
14449#endif
14450 dbm);
14451 vos_ssr_unprotect(__func__);
14452
14453 return ret;
14454}
14455
Jeff Johnson295189b2012-06-20 16:38:30 -070014456/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014457 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014458 * This function is used to read the txpower
14459 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014460static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014461#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14462 struct wireless_dev *wdev,
14463#endif
14464 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070014465{
14466
14467 hdd_adapter_t *pAdapter;
14468 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014469 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014470
Jeff Johnsone7245742012-09-05 17:12:55 -070014471 ENTER();
14472
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014473 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014474 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014476 *dbm = 0;
14477 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014478 }
14479
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
14481 if (NULL == pAdapter)
14482 {
14483 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
14484 return -ENOENT;
14485 }
14486
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14488 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
14489 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 wlan_hdd_get_classAstats(pAdapter);
14491 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
14492
Jeff Johnsone7245742012-09-05 17:12:55 -070014493 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014494 return 0;
14495}
14496
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014497static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
14498#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14499 struct wireless_dev *wdev,
14500#endif
14501 int *dbm)
14502{
14503 int ret;
14504
14505 vos_ssr_protect(__func__);
14506 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
14507#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14508 wdev,
14509#endif
14510 dbm);
14511 vos_ssr_unprotect(__func__);
14512
14513 return ret;
14514}
14515
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014516static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014517#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14518 const u8* mac,
14519#else
14520 u8* mac,
14521#endif
14522 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070014523{
14524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14525 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14526 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053014527 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014528
14529 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
14530 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070014531
14532 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
14533 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
14534 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
14535 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
14536 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
14537 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
14538 tANI_U16 maxRate = 0;
14539 tANI_U16 myRate;
14540 tANI_U16 currentRate = 0;
14541 tANI_U8 maxSpeedMCS = 0;
14542 tANI_U8 maxMCSIdx = 0;
14543 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014544 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014545 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014546 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014547
Leo Chang6f8870f2013-03-26 18:11:36 -070014548#ifdef WLAN_FEATURE_11AC
14549 tANI_U32 vht_mcs_map;
14550 eDataRate11ACMaxMcs vhtMaxMcs;
14551#endif /* WLAN_FEATURE_11AC */
14552
Jeff Johnsone7245742012-09-05 17:12:55 -070014553 ENTER();
14554
Jeff Johnson295189b2012-06-20 16:38:30 -070014555 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14556 (0 == ssidlen))
14557 {
14558 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14559 " Invalid ssidlen, %d", __func__, ssidlen);
14560 /*To keep GUI happy*/
14561 return 0;
14562 }
14563
Mukul Sharma811205f2014-07-09 21:07:30 +053014564 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14565 {
14566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14567 "%s: Roaming in progress, so unable to proceed this request", __func__);
14568 return 0;
14569 }
14570
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014571 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014572 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014574 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575 }
14576
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014577 wlan_hdd_get_station_stats(pAdapter);
14578 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014579
Kiet Lam3b17fc82013-09-27 05:24:08 +053014580 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14581 sinfo->filled |= STATION_INFO_SIGNAL;
14582
c_hpothu09f19542014-05-30 21:53:31 +053014583 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014584 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14585 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014586 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014587 {
14588 rate_flags = pAdapter->maxRateFlags;
14589 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014590
Jeff Johnson295189b2012-06-20 16:38:30 -070014591 //convert to the UI units of 100kbps
14592 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14593
14594#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014595 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 -070014596 sinfo->signal,
14597 pCfg->reportMaxLinkSpeed,
14598 myRate,
14599 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014600 (int) pCfg->linkSpeedRssiMid,
14601 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014602 (int) rate_flags,
14603 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014604#endif //LINKSPEED_DEBUG_ENABLED
14605
14606 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14607 {
14608 // we do not want to necessarily report the current speed
14609 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14610 {
14611 // report the max possible speed
14612 rssidx = 0;
14613 }
14614 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14615 {
14616 // report the max possible speed with RSSI scaling
14617 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14618 {
14619 // report the max possible speed
14620 rssidx = 0;
14621 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014622 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014623 {
14624 // report middle speed
14625 rssidx = 1;
14626 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014627 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14628 {
14629 // report middle speed
14630 rssidx = 2;
14631 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014632 else
14633 {
14634 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014635 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014636 }
14637 }
14638 else
14639 {
14640 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14641 hddLog(VOS_TRACE_LEVEL_ERROR,
14642 "%s: Invalid value for reportMaxLinkSpeed: %u",
14643 __func__, pCfg->reportMaxLinkSpeed);
14644 rssidx = 0;
14645 }
14646
14647 maxRate = 0;
14648
14649 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014650 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14651 OperationalRates, &ORLeng))
14652 {
14653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14654 /*To keep GUI happy*/
14655 return 0;
14656 }
14657
Jeff Johnson295189b2012-06-20 16:38:30 -070014658 for (i = 0; i < ORLeng; i++)
14659 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014660 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014661 {
14662 /* Validate Rate Set */
14663 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14664 {
14665 currentRate = supported_data_rate[j].supported_rate[rssidx];
14666 break;
14667 }
14668 }
14669 /* Update MAX rate */
14670 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14671 }
14672
14673 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014674 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14675 ExtendedRates, &ERLeng))
14676 {
14677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14678 /*To keep GUI happy*/
14679 return 0;
14680 }
14681
Jeff Johnson295189b2012-06-20 16:38:30 -070014682 for (i = 0; i < ERLeng; i++)
14683 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014684 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014685 {
14686 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14687 {
14688 currentRate = supported_data_rate[j].supported_rate[rssidx];
14689 break;
14690 }
14691 }
14692 /* Update MAX rate */
14693 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14694 }
c_hpothu79aab322014-07-14 21:11:01 +053014695
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014696 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014697 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014698 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014699 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 {
c_hpothu79aab322014-07-14 21:11:01 +053014701 if (rate_flags & eHAL_TX_RATE_VHT80)
14702 mode = 2;
14703 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14704 mode = 1;
14705 else
14706 mode = 0;
14707
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014708 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14709 MCSRates, &MCSLeng))
14710 {
14711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14712 /*To keep GUI happy*/
14713 return 0;
14714 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014716#ifdef WLAN_FEATURE_11AC
14717 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014718 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014720 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014721 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014722 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014723 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014724 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014726 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014727 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014728 maxMCSIdx = 7;
14729 }
14730 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14731 {
14732 maxMCSIdx = 8;
14733 }
14734 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14735 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014736 //VHT20 is supporting 0~8
14737 if (rate_flags & eHAL_TX_RATE_VHT20)
14738 maxMCSIdx = 8;
14739 else
14740 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014741 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014742
c_hpothu79aab322014-07-14 21:11:01 +053014743 if (0 != rssidx)/*check for scaled */
14744 {
14745 //get middle rate MCS index if rssi=1/2
14746 for (i=0; i <= maxMCSIdx; i++)
14747 {
14748 if (sinfo->signal <= rssiMcsTbl[mode][i])
14749 {
14750 maxMCSIdx = i;
14751 break;
14752 }
14753 }
14754 }
14755
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014756 if (rate_flags & eHAL_TX_RATE_VHT80)
14757 {
14758 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14759 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14760 }
14761 else if (rate_flags & eHAL_TX_RATE_VHT40)
14762 {
14763 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14764 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14765 }
14766 else if (rate_flags & eHAL_TX_RATE_VHT20)
14767 {
14768 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14769 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14770 }
14771
Leo Chang6f8870f2013-03-26 18:11:36 -070014772 maxSpeedMCS = 1;
14773 if (currentRate > maxRate)
14774 {
14775 maxRate = currentRate;
14776 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014777
Leo Chang6f8870f2013-03-26 18:11:36 -070014778 }
14779 else
14780#endif /* WLAN_FEATURE_11AC */
14781 {
14782 if (rate_flags & eHAL_TX_RATE_HT40)
14783 {
14784 rateFlag |= 1;
14785 }
14786 if (rate_flags & eHAL_TX_RATE_SGI)
14787 {
14788 rateFlag |= 2;
14789 }
14790
Girish Gowli01abcee2014-07-31 20:18:55 +053014791 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014792 if (rssidx == 1 || rssidx == 2)
14793 {
14794 //get middle rate MCS index if rssi=1/2
14795 for (i=0; i <= 7; i++)
14796 {
14797 if (sinfo->signal <= rssiMcsTbl[mode][i])
14798 {
14799 temp = i+1;
14800 break;
14801 }
14802 }
14803 }
c_hpothu79aab322014-07-14 21:11:01 +053014804
14805 for (i = 0; i < MCSLeng; i++)
14806 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014807 for (j = 0; j < temp; j++)
14808 {
14809 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14810 {
14811 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014812 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014813 break;
14814 }
14815 }
14816 if ((j < temp) && (currentRate > maxRate))
14817 {
14818 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014819 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014820 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014821 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014822 }
14823 }
14824
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014825 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14826 {
14827 maxRate = myRate;
14828 maxSpeedMCS = 1;
14829 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14830 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014831 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014832 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014833 {
14834 maxRate = myRate;
14835 if (rate_flags & eHAL_TX_RATE_LEGACY)
14836 {
14837 maxSpeedMCS = 0;
14838 }
14839 else
14840 {
14841 maxSpeedMCS = 1;
14842 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14843 }
14844 }
14845
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014846 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 {
14848 sinfo->txrate.legacy = maxRate;
14849#ifdef LINKSPEED_DEBUG_ENABLED
14850 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14851#endif //LINKSPEED_DEBUG_ENABLED
14852 }
14853 else
14854 {
14855 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014856#ifdef WLAN_FEATURE_11AC
14857 sinfo->txrate.nss = 1;
14858 if (rate_flags & eHAL_TX_RATE_VHT80)
14859 {
14860 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014861 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014862 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014863 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014864 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014865 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14866 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14867 }
14868 else if (rate_flags & eHAL_TX_RATE_VHT20)
14869 {
14870 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14871 }
14872#endif /* WLAN_FEATURE_11AC */
14873 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14874 {
14875 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14876 if (rate_flags & eHAL_TX_RATE_HT40)
14877 {
14878 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14879 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014880 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 if (rate_flags & eHAL_TX_RATE_SGI)
14882 {
14883 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14884 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014885
Jeff Johnson295189b2012-06-20 16:38:30 -070014886#ifdef LINKSPEED_DEBUG_ENABLED
14887 pr_info("Reporting MCS rate %d flags %x\n",
14888 sinfo->txrate.mcs,
14889 sinfo->txrate.flags );
14890#endif //LINKSPEED_DEBUG_ENABLED
14891 }
14892 }
14893 else
14894 {
14895 // report current rate instead of max rate
14896
14897 if (rate_flags & eHAL_TX_RATE_LEGACY)
14898 {
14899 //provide to the UI in units of 100kbps
14900 sinfo->txrate.legacy = myRate;
14901#ifdef LINKSPEED_DEBUG_ENABLED
14902 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14903#endif //LINKSPEED_DEBUG_ENABLED
14904 }
14905 else
14906 {
14907 //must be MCS
14908 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014909#ifdef WLAN_FEATURE_11AC
14910 sinfo->txrate.nss = 1;
14911 if (rate_flags & eHAL_TX_RATE_VHT80)
14912 {
14913 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14914 }
14915 else
14916#endif /* WLAN_FEATURE_11AC */
14917 {
14918 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14919 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 if (rate_flags & eHAL_TX_RATE_SGI)
14921 {
14922 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14923 }
14924 if (rate_flags & eHAL_TX_RATE_HT40)
14925 {
14926 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14927 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014928#ifdef WLAN_FEATURE_11AC
14929 else if (rate_flags & eHAL_TX_RATE_VHT80)
14930 {
14931 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14932 }
14933#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014934#ifdef LINKSPEED_DEBUG_ENABLED
14935 pr_info("Reporting actual MCS rate %d flags %x\n",
14936 sinfo->txrate.mcs,
14937 sinfo->txrate.flags );
14938#endif //LINKSPEED_DEBUG_ENABLED
14939 }
14940 }
14941 sinfo->filled |= STATION_INFO_TX_BITRATE;
14942
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014943 sinfo->tx_packets =
14944 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14945 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14946 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14947 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14948
14949 sinfo->tx_retries =
14950 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14951 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14952 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14953 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14954
14955 sinfo->tx_failed =
14956 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14957 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14958 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14959 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14960
14961 sinfo->filled |=
14962 STATION_INFO_TX_PACKETS |
14963 STATION_INFO_TX_RETRIES |
14964 STATION_INFO_TX_FAILED;
14965
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014966 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14967 TRACE_CODE_HDD_CFG80211_GET_STA,
14968 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014969 EXIT();
14970 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014971}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14973static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14974 const u8* mac, struct station_info *sinfo)
14975#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014976static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14977 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014978#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014979{
14980 int ret;
14981
14982 vos_ssr_protect(__func__);
14983 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14984 vos_ssr_unprotect(__func__);
14985
14986 return ret;
14987}
14988
14989static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014990 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014991{
14992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014993 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014994 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014995 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014996
Jeff Johnsone7245742012-09-05 17:12:55 -070014997 ENTER();
14998
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 if (NULL == pAdapter)
15000 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 return -ENODEV;
15003 }
15004
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015005 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15006 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15007 pAdapter->sessionId, timeout));
15008
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015010 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015011 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015012 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015013 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015014 }
15015
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015016 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15017 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15018 (pHddCtx->cfg_ini->fhostArpOffload) &&
15019 (eConnectionState_Associated ==
15020 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15021 {
Amar Singhald53568e2013-09-26 11:03:45 -070015022
15023 hddLog(VOS_TRACE_LEVEL_INFO,
15024 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015025 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015026 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15027 {
15028 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015029 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015030 __func__, vos_status);
15031 }
15032 }
15033
Jeff Johnson295189b2012-06-20 16:38:30 -070015034 /**The get power cmd from the supplicant gets updated by the nl only
15035 *on successful execution of the function call
15036 *we are oppositely mapped w.r.t mode in the driver
15037 **/
15038 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15039
15040 if (VOS_STATUS_E_FAILURE == vos_status)
15041 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15043 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015044 return -EINVAL;
15045 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015046 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015047 return 0;
15048}
15049
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015050static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15051 struct net_device *dev, bool mode, int timeout)
15052{
15053 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015054
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015055 vos_ssr_protect(__func__);
15056 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15057 vos_ssr_unprotect(__func__);
15058
15059 return ret;
15060}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015061
Jeff Johnson295189b2012-06-20 16:38:30 -070015062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015063static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15064 struct net_device *netdev,
15065 u8 key_index)
15066{
15067 ENTER();
15068 return 0;
15069}
15070
Jeff Johnson295189b2012-06-20 16:38:30 -070015071static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015072 struct net_device *netdev,
15073 u8 key_index)
15074{
15075 int ret;
15076 vos_ssr_protect(__func__);
15077 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15078 vos_ssr_unprotect(__func__);
15079 return ret;
15080}
15081#endif //LINUX_VERSION_CODE
15082
15083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15084static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15085 struct net_device *dev,
15086 struct ieee80211_txq_params *params)
15087{
15088 ENTER();
15089 return 0;
15090}
15091#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15092static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15093 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015094{
Jeff Johnsone7245742012-09-05 17:12:55 -070015095 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 return 0;
15097}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015098#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015099
15100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15101static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015102 struct net_device *dev,
15103 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015104{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015105 int ret;
15106
15107 vos_ssr_protect(__func__);
15108 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15109 vos_ssr_unprotect(__func__);
15110 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015111}
15112#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15113static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15114 struct ieee80211_txq_params *params)
15115{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015116 int ret;
15117
15118 vos_ssr_protect(__func__);
15119 ret = __wlan_hdd_set_txq_params(wiphy, params);
15120 vos_ssr_unprotect(__func__);
15121 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015122}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015123#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015124
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015125static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015126 struct net_device *dev,
15127 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015128{
15129 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015130 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015131 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015132 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015133 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015134 v_CONTEXT_t pVosContext = NULL;
15135 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015136
Jeff Johnsone7245742012-09-05 17:12:55 -070015137 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015138
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015139 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015142 return -EINVAL;
15143 }
15144
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15146 TRACE_CODE_HDD_CFG80211_DEL_STA,
15147 pAdapter->sessionId, pAdapter->device_mode));
15148
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015149 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15150 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015151 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015152 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015153 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015154 }
15155
Jeff Johnson295189b2012-06-20 16:38:30 -070015156 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015157 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015158 )
15159 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015160 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15161 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15162 if(pSapCtx == NULL){
15163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15164 FL("psapCtx is NULL"));
15165 return -ENOENT;
15166 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015167 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070015168 {
15169 v_U16_t i;
15170 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15171 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015172 if ((pSapCtx->aStaInfo[i].isUsed) &&
15173 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070015174 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015175 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015176 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015177 ETHER_ADDR_LEN);
15178
Jeff Johnson295189b2012-06-20 16:38:30 -070015179 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015180 "%s: Delete STA with MAC::"
15181 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015182 __func__,
15183 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
15184 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070015185 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015186 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015187 }
15188 }
15189 }
15190 else
15191 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015192
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015193 vos_status = hdd_softap_GetStaId(pAdapter,
15194 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015195 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15196 {
15197 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015198 "%s: Skip this DEL STA as this is not used::"
15199 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015200 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015201 return -ENOENT;
15202 }
15203
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015204 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015205 {
15206 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015207 "%s: Skip this DEL STA as deauth is in progress::"
15208 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015209 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015210 return -ENOENT;
15211 }
15212
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015213 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015214
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 hddLog(VOS_TRACE_LEVEL_INFO,
15216 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080015217 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015218 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015219 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015220
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015221 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015222 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15223 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015224 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015225 hddLog(VOS_TRACE_LEVEL_INFO,
15226 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080015227 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015228 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015229 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015230 return -ENOENT;
15231 }
15232
Jeff Johnson295189b2012-06-20 16:38:30 -070015233 }
15234 }
15235
15236 EXIT();
15237
15238 return 0;
15239}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015240
15241#ifdef CFG80211_DEL_STA_V2
15242static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15243 struct net_device *dev,
15244 struct station_del_parameters *param)
15245#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15247static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15248 struct net_device *dev, const u8 *mac)
15249#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015250static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15251 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015252#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015253#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015254{
15255 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015256 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070015257
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015258 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015259
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015260#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015261 if (NULL == param) {
15262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015263 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015264 return -EINVAL;
15265 }
15266
15267 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
15268 param->subtype, &delStaParams);
15269
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015270#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015271 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015272 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015273#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015274 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
15275
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015276 vos_ssr_unprotect(__func__);
15277
15278 return ret;
15279}
15280
15281static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015282 struct net_device *dev,
15283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15284 const u8 *mac,
15285#else
15286 u8 *mac,
15287#endif
15288 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015289{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015290 hdd_adapter_t *pAdapter;
15291 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015292 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015293#ifdef FEATURE_WLAN_TDLS
15294 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015295
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015296 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015297
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015298 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15299 if (NULL == pAdapter)
15300 {
15301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15302 "%s: Adapter is NULL",__func__);
15303 return -EINVAL;
15304 }
15305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15306 status = wlan_hdd_validate_context(pHddCtx);
15307 if (0 != status)
15308 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015309 return status;
15310 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15313 TRACE_CODE_HDD_CFG80211_ADD_STA,
15314 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015315 mask = params->sta_flags_mask;
15316
15317 set = params->sta_flags_set;
15318
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015320 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
15321 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015322
15323 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
15324 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015325 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015326 }
15327 }
15328#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015329 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015330 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015331}
15332
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15334static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15335 struct net_device *dev, const u8 *mac,
15336 struct station_parameters *params)
15337#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015338static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15339 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015340#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015341{
15342 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015343
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015344 vos_ssr_protect(__func__);
15345 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
15346 vos_ssr_unprotect(__func__);
15347
15348 return ret;
15349}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015350#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070015351
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015352static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070015353 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015354{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15356 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015357 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015358 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015359 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015360 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070015361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015362 ENTER();
15363
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015364 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015365 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015368 return -EINVAL;
15369 }
15370
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015371 if (!pmksa) {
15372 hddLog(LOGE, FL("pmksa is NULL"));
15373 return -EINVAL;
15374 }
15375
15376 if (!pmksa->bssid || !pmksa->pmkid) {
15377 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
15378 pmksa->bssid, pmksa->pmkid);
15379 return -EINVAL;
15380 }
15381
15382 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
15383 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15384
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15386 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015387 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015388 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015389 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015390 }
15391
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015392 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015393 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15394
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015395 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
15396 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015397
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015398 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015399 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015400 &pmk_id, 1, FALSE);
15401
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015402 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15403 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
15404 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015405
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015406 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015407 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015408}
15409
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015410static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
15411 struct cfg80211_pmksa *pmksa)
15412{
15413 int ret;
15414
15415 vos_ssr_protect(__func__);
15416 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
15417 vos_ssr_unprotect(__func__);
15418
15419 return ret;
15420}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015421
Wilson Yang6507c4e2013-10-01 20:11:19 -070015422
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015423static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070015424 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015425{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15427 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015428 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015429 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015431 ENTER();
15432
Wilson Yang6507c4e2013-10-01 20:11:19 -070015433 /* Validate pAdapter */
15434 if (NULL == pAdapter)
15435 {
15436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
15437 return -EINVAL;
15438 }
15439
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015440 if (!pmksa) {
15441 hddLog(LOGE, FL("pmksa is NULL"));
15442 return -EINVAL;
15443 }
15444
15445 if (!pmksa->bssid) {
15446 hddLog(LOGE, FL("pmksa->bssid is NULL"));
15447 return -EINVAL;
15448 }
15449
Kiet Lam98c46a12014-10-31 15:34:57 -070015450 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
15451 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15452
Wilson Yang6507c4e2013-10-01 20:11:19 -070015453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15454 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015455 if (0 != status)
15456 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015457 return status;
15458 }
15459
15460 /*Retrieve halHandle*/
15461 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15462
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015463 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15464 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
15465 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015466 /* Delete the PMKID CSR cache */
15467 if (eHAL_STATUS_SUCCESS !=
15468 sme_RoamDelPMKIDfromCache(halHandle,
15469 pAdapter->sessionId, pmksa->bssid, FALSE)) {
15470 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
15471 MAC_ADDR_ARRAY(pmksa->bssid));
15472 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015473 }
15474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015475 EXIT();
15476 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015477}
15478
Wilson Yang6507c4e2013-10-01 20:11:19 -070015479
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015480static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
15481 struct cfg80211_pmksa *pmksa)
15482{
15483 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015484
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015485 vos_ssr_protect(__func__);
15486 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
15487 vos_ssr_unprotect(__func__);
15488
15489 return ret;
15490
15491}
15492
15493static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015494{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015495 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15496 tHalHandle halHandle;
15497 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015498 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015499
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015500 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070015501
15502 /* Validate pAdapter */
15503 if (NULL == pAdapter)
15504 {
15505 hddLog(VOS_TRACE_LEVEL_ERROR,
15506 "%s: Invalid Adapter" ,__func__);
15507 return -EINVAL;
15508 }
15509
15510 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15511 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015512 if (0 != status)
15513 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015514 return status;
15515 }
15516
15517 /*Retrieve halHandle*/
15518 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15519
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015520 /* Flush the PMKID cache in CSR */
15521 if (eHAL_STATUS_SUCCESS !=
15522 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
15523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
15524 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015525 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015526 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080015527 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015528}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015529
15530static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
15531{
15532 int ret;
15533
15534 vos_ssr_protect(__func__);
15535 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
15536 vos_ssr_unprotect(__func__);
15537
15538 return ret;
15539}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015540#endif
15541
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015542#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015543static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15544 struct net_device *dev,
15545 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015546{
15547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15548 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015549 hdd_context_t *pHddCtx;
15550 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015552 ENTER();
15553
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015554 if (NULL == pAdapter)
15555 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015557 return -ENODEV;
15558 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015559 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15560 ret = wlan_hdd_validate_context(pHddCtx);
15561 if (0 != ret)
15562 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015563 return ret;
15564 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015565 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015566 if (NULL == pHddStaCtx)
15567 {
15568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15569 return -EINVAL;
15570 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015571
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15573 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15574 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015575 // Added for debug on reception of Re-assoc Req.
15576 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15577 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015578 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015579 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015580 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015581 }
15582
15583#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015584 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015585 ftie->ie_len);
15586#endif
15587
15588 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015589 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15590 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015591 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015592
15593 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015594 return 0;
15595}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015596
15597static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15598 struct net_device *dev,
15599 struct cfg80211_update_ft_ies_params *ftie)
15600{
15601 int ret;
15602
15603 vos_ssr_protect(__func__);
15604 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15605 vos_ssr_unprotect(__func__);
15606
15607 return ret;
15608}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015609#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015610
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015611#ifdef FEATURE_WLAN_SCAN_PNO
15612
15613void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15614 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15615{
15616 int ret;
15617 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15618 hdd_context_t *pHddCtx;
15619
Nirav Shah80830bf2013-12-31 16:35:12 +053015620 ENTER();
15621
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015622 if (NULL == pAdapter)
15623 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015625 "%s: HDD adapter is Null", __func__);
15626 return ;
15627 }
15628
15629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15630 if (NULL == pHddCtx)
15631 {
15632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15633 "%s: HDD context is Null!!!", __func__);
15634 return ;
15635 }
15636
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015637 spin_lock(&pHddCtx->schedScan_lock);
15638 if (TRUE == pHddCtx->isWiphySuspended)
15639 {
15640 pHddCtx->isSchedScanUpdatePending = TRUE;
15641 spin_unlock(&pHddCtx->schedScan_lock);
15642 hddLog(VOS_TRACE_LEVEL_INFO,
15643 "%s: Update cfg80211 scan database after it resume", __func__);
15644 return ;
15645 }
15646 spin_unlock(&pHddCtx->schedScan_lock);
15647
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015648 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15649
15650 if (0 > ret)
15651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15652
15653 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15655 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015656}
15657
15658/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015659 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015660 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015661 */
15662static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15663{
15664 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15665 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015666 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15668 int status = 0;
15669 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15670
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015671 /* The current firmware design does not allow PNO during any
15672 * active sessions. Hence, determine the active sessions
15673 * and return a failure.
15674 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015675 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15676 {
15677 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015678 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015679
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015680 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15681 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15682 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15683 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15684 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015685 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015686 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015687 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015688 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015689 }
15690 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15691 pAdapterNode = pNext;
15692 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015693 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015694}
15695
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015696void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15697{
15698 hdd_adapter_t *pAdapter = callbackContext;
15699 hdd_context_t *pHddCtx;
15700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015701 ENTER();
15702
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015703 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15704 {
15705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15706 FL("Invalid adapter or adapter has invalid magic"));
15707 return;
15708 }
15709
15710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15711 if (0 != wlan_hdd_validate_context(pHddCtx))
15712 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015713 return;
15714 }
15715
c_hpothub53c45d2014-08-18 16:53:14 +053015716 if (VOS_STATUS_SUCCESS != status)
15717 {
15718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015719 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015720 pHddCtx->isPnoEnable = FALSE;
15721 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015722
15723 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15724 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015725 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015726}
15727
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015728/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015729 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15730 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015731 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015732static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015733 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15734{
15735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015736 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015737 hdd_context_t *pHddCtx;
15738 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015739 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015740 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15741 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015742 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15743 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015744 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015745 hdd_config_t *pConfig = NULL;
15746 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015747
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015748 ENTER();
15749
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015750 if (NULL == pAdapter)
15751 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015753 "%s: HDD adapter is Null", __func__);
15754 return -ENODEV;
15755 }
15756
15757 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015758 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015759
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015760 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015761 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015762 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015763 }
15764
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015765 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015766 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15767 if (NULL == hHal)
15768 {
15769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15770 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015771 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015772 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015773 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15774 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15775 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015776 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015777 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015778 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015779 {
15780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15781 "%s: aborting the existing scan is unsuccessfull", __func__);
15782 return -EBUSY;
15783 }
15784
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015785 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015786 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015788 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015789 return -EBUSY;
15790 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015791
c_hpothu37f21312014-04-09 21:49:54 +053015792 if (TRUE == pHddCtx->isPnoEnable)
15793 {
15794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15795 FL("already PNO is enabled"));
15796 return -EBUSY;
15797 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015798
15799 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15800 {
15801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15802 "%s: abort ROC failed ", __func__);
15803 return -EBUSY;
15804 }
15805
c_hpothu37f21312014-04-09 21:49:54 +053015806 pHddCtx->isPnoEnable = TRUE;
15807
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015808 pnoRequest.enable = 1; /*Enable PNO */
15809 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015810
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015811 if (( !pnoRequest.ucNetworksCount ) ||
15812 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015813 {
15814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015815 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015816 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015817 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015818 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015819 goto error;
15820 }
15821
15822 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15823 {
15824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015825 "%s: Incorrect number of channels %d",
15826 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015827 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015828 goto error;
15829 }
15830
15831 /* Framework provides one set of channels(all)
15832 * common for all saved profile */
15833 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15834 channels_allowed, &num_channels_allowed))
15835 {
15836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15837 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015838 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015839 goto error;
15840 }
15841 /* Checking each channel against allowed channel list */
15842 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015843 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015844 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015845 char chList [(request->n_channels*5)+1];
15846 int len;
15847 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015848 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015849 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015850 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015851 if (request->channels[i]->hw_value == channels_allowed[indx])
15852 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015853 if ((!pConfig->enableDFSPnoChnlScan) &&
15854 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15855 {
15856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15857 "%s : Dropping DFS channel : %d",
15858 __func__,channels_allowed[indx]);
15859 num_ignore_dfs_ch++;
15860 break;
15861 }
15862
Nirav Shah80830bf2013-12-31 16:35:12 +053015863 valid_ch[num_ch++] = request->channels[i]->hw_value;
15864 len += snprintf(chList+len, 5, "%d ",
15865 request->channels[i]->hw_value);
15866 break ;
15867 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015868 }
15869 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015870 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015871
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015872 /*If all channels are DFS and dropped, then ignore the PNO request*/
15873 if (num_ignore_dfs_ch == request->n_channels)
15874 {
15875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15876 "%s : All requested channels are DFS channels", __func__);
15877 ret = -EINVAL;
15878 goto error;
15879 }
15880 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015881
15882 pnoRequest.aNetworks =
15883 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15884 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015885 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015886 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15887 FL("failed to allocate memory aNetworks %u"),
15888 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15889 goto error;
15890 }
15891 vos_mem_zero(pnoRequest.aNetworks,
15892 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15893
15894 /* Filling per profile params */
15895 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15896 {
15897 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015898 request->match_sets[i].ssid.ssid_len;
15899
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015900 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15901 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015902 {
15903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015904 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015905 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015906 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015907 goto error;
15908 }
15909
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015910 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015911 request->match_sets[i].ssid.ssid,
15912 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15914 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015915 i, pnoRequest.aNetworks[i].ssId.ssId);
15916 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15917 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15918 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015919
15920 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015921 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15922 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015923
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015924 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015925 }
15926
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015927 for (i = 0; i < request->n_ssids; i++)
15928 {
15929 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015930 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015931 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015932 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015933 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015934 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015935 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015936 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015937 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015938 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015939 break;
15940 }
15941 j++;
15942 }
15943 }
15944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15945 "Number of hidden networks being Configured = %d",
15946 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015948 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015949
15950 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15951 if (pnoRequest.p24GProbeTemplate == NULL)
15952 {
15953 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15954 FL("failed to allocate memory p24GProbeTemplate %u"),
15955 SIR_PNO_MAX_PB_REQ_SIZE);
15956 goto error;
15957 }
15958
15959 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15960 if (pnoRequest.p5GProbeTemplate == NULL)
15961 {
15962 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15963 FL("failed to allocate memory p5GProbeTemplate %u"),
15964 SIR_PNO_MAX_PB_REQ_SIZE);
15965 goto error;
15966 }
15967
15968 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15969 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15970
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015971 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15972 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015973 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015974 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15975 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15976 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015977
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015978 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15979 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15980 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015981 }
15982
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015983 /* Driver gets only one time interval which is hardcoded in
15984 * supplicant for 10000ms. Taking power consumption into account 6 timers
15985 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15986 * 80,160,320 secs. And number of scan cycle for each timer
15987 * is configurable through INI param gPNOScanTimerRepeatValue.
15988 * If it is set to 0 only one timer will be used and PNO scan cycle
15989 * will be repeated after each interval specified by supplicant
15990 * till PNO is disabled.
15991 */
15992 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015993 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015994 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015995 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015996 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15997
15998 tempInterval = (request->interval)/1000;
15999 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16000 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16001 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016002 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016003 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016004 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016005 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016006 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016007 tempInterval *= 2;
16008 }
16009 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016010 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016011
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016012 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016013
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016014 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016015 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16016 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016017 pAdapter->pno_req_status = 0;
16018
Nirav Shah80830bf2013-12-31 16:35:12 +053016019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16020 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016021 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16022 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016023
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016024 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016025 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016026 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16027 if (eHAL_STATUS_SUCCESS != status)
16028 {
16029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016030 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016031 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016032 goto error;
16033 }
16034
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016035 ret = wait_for_completion_timeout(
16036 &pAdapter->pno_comp_var,
16037 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16038 if (0 >= ret)
16039 {
16040 // Did not receive the response for PNO enable in time.
16041 // Assuming the PNO enable was success.
16042 // Returning error from here, because we timeout, results
16043 // in side effect of Wifi (Wifi Setting) not to work.
16044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16045 FL("Timed out waiting for PNO to be Enabled"));
16046 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016047 }
16048
16049 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016050 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016051
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016052error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16054 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016055 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016056 if (pnoRequest.aNetworks)
16057 vos_mem_free(pnoRequest.aNetworks);
16058 if (pnoRequest.p24GProbeTemplate)
16059 vos_mem_free(pnoRequest.p24GProbeTemplate);
16060 if (pnoRequest.p5GProbeTemplate)
16061 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016062
16063 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016064 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016065}
16066
16067/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016068 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16069 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016070 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016071static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16072 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16073{
16074 int ret;
16075
16076 vos_ssr_protect(__func__);
16077 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16078 vos_ssr_unprotect(__func__);
16079
16080 return ret;
16081}
16082
16083/*
16084 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16085 * Function to disable PNO
16086 */
16087static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016088 struct net_device *dev)
16089{
16090 eHalStatus status = eHAL_STATUS_FAILURE;
16091 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16092 hdd_context_t *pHddCtx;
16093 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016094 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016095 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016096
16097 ENTER();
16098
16099 if (NULL == pAdapter)
16100 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016102 "%s: HDD adapter is Null", __func__);
16103 return -ENODEV;
16104 }
16105
16106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016107
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016108 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016109 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016111 "%s: HDD context is Null", __func__);
16112 return -ENODEV;
16113 }
16114
16115 /* The return 0 is intentional when isLogpInProgress and
16116 * isLoadUnloadInProgress. We did observe a crash due to a return of
16117 * failure in sched_scan_stop , especially for a case where the unload
16118 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16119 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16120 * success. If it returns a failure , then its next invocation due to the
16121 * clean up of the second interface will have the dev pointer corresponding
16122 * to the first one leading to a crash.
16123 */
16124 if (pHddCtx->isLogpInProgress)
16125 {
16126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16127 "%s: LOGP in Progress. Ignore!!!", __func__);
16128 return ret;
16129 }
16130
Mihir Shete18156292014-03-11 15:38:30 +053016131 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016132 {
16133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16134 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16135 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016136 }
16137
16138 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16139 if (NULL == hHal)
16140 {
16141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16142 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016143 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016144 }
16145
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016146 pnoRequest.enable = 0; /* Disable PNO */
16147 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016148
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016149 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16150 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
16151 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016152 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016153 pAdapter->sessionId,
16154 NULL, pAdapter);
16155 if (eHAL_STATUS_SUCCESS != status)
16156 {
16157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16158 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016159 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016160 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016161 }
c_hpothu37f21312014-04-09 21:49:54 +053016162 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016163
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016164error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016166 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016167
16168 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016169 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016170}
16171
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016172/*
16173 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
16174 * NL interface to disable PNO
16175 */
16176static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
16177 struct net_device *dev)
16178{
16179 int ret;
16180
16181 vos_ssr_protect(__func__);
16182 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
16183 vos_ssr_unprotect(__func__);
16184
16185 return ret;
16186}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016187#endif /*FEATURE_WLAN_SCAN_PNO*/
16188
16189
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016190#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016191#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016192static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16193 struct net_device *dev,
16194 u8 *peer, u8 action_code,
16195 u8 dialog_token,
16196 u16 status_code, u32 peer_capability,
16197 const u8 *buf, size_t len)
16198#else /* TDLS_MGMT_VERSION2 */
16199#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16200static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16201 struct net_device *dev,
16202 const u8 *peer, u8 action_code,
16203 u8 dialog_token, u16 status_code,
16204 u32 peer_capability, bool initiator,
16205 const u8 *buf, size_t len)
16206#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16207static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16208 struct net_device *dev,
16209 const u8 *peer, u8 action_code,
16210 u8 dialog_token, u16 status_code,
16211 u32 peer_capability, const u8 *buf,
16212 size_t len)
16213#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16214static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16215 struct net_device *dev,
16216 u8 *peer, u8 action_code,
16217 u8 dialog_token,
16218 u16 status_code, u32 peer_capability,
16219 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016220#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016221static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16222 struct net_device *dev,
16223 u8 *peer, u8 action_code,
16224 u8 dialog_token,
16225 u16 status_code, const u8 *buf,
16226 size_t len)
16227#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016228#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016229{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016230 hdd_adapter_t *pAdapter;
16231 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016232 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070016233 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080016234 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070016235 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016236 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016237#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016238 u32 peer_capability = 0;
16239#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016240 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016241 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016242
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016243 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16244 if (NULL == pAdapter)
16245 {
16246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16247 "%s: Adapter is NULL",__func__);
16248 return -EINVAL;
16249 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016250 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16251 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
16252 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016253
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016254 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016255 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016258 "Invalid arguments");
16259 return -EINVAL;
16260 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016261
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016262 if (pHddCtx->isLogpInProgress)
16263 {
16264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16265 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053016266 wlan_hdd_tdls_set_link_status(pAdapter,
16267 peer,
16268 eTDLS_LINK_IDLE,
16269 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016270 return -EBUSY;
16271 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016272
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016273 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
16274 {
16275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16276 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16277 return -EAGAIN;
16278 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016279
Hoonki Lee27511902013-03-14 18:19:06 -070016280 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016281 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070016283 "%s: TDLS mode is disabled OR not enabled in FW."
16284 MAC_ADDRESS_STR " action %d declined.",
16285 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016286 return -ENOTSUPP;
16287 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016288
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016289 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16290
16291 if( NULL == pHddStaCtx )
16292 {
16293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16294 "%s: HDD station context NULL ",__func__);
16295 return -EINVAL;
16296 }
16297
16298 /* STA should be connected and authenticated
16299 * before sending any TDLS frames
16300 */
16301 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16302 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
16303 {
16304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16305 "STA is not connected or unauthenticated. "
16306 "connState %u, uIsAuthenticated %u",
16307 pHddStaCtx->conn_info.connState,
16308 pHddStaCtx->conn_info.uIsAuthenticated);
16309 return -EAGAIN;
16310 }
16311
Hoonki Lee27511902013-03-14 18:19:06 -070016312 /* other than teardown frame, other mgmt frames are not sent if disabled */
16313 if (SIR_MAC_TDLS_TEARDOWN != action_code)
16314 {
16315 /* if tdls_mode is disabled to respond to peer's request */
16316 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
16317 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070016319 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016320 " TDLS mode is disabled. action %d declined.",
16321 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070016322
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016323 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070016324 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053016325
16326 if (vos_max_concurrent_connections_reached())
16327 {
16328 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16329 return -EINVAL;
16330 }
Hoonki Lee27511902013-03-14 18:19:06 -070016331 }
16332
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016333 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
16334 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053016335 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016336 {
16337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016338 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016339 " TDLS setup is ongoing. action %d declined.",
16340 __func__, MAC_ADDR_ARRAY(peer), action_code);
16341 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016342 }
16343 }
16344
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016345 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
16346 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080016347 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016348 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16349 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016350 {
16351 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
16352 we return error code at 'add_station()'. Hence we have this
16353 check again in addtion to add_station().
16354 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016355 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016356 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16358 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016359 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
16360 __func__, MAC_ADDR_ARRAY(peer), action_code,
16361 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053016362 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080016363 }
16364 else
16365 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016366 /* maximum reached. tweak to send error code to peer and return
16367 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016368 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16370 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016371 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
16372 __func__, MAC_ADDR_ARRAY(peer), status_code,
16373 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070016374 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016375 /* fall through to send setup resp with failure status
16376 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016377 }
16378 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016379 else
16380 {
16381 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053016382 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016383 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016384 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016386 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
16387 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016388 return -EPERM;
16389 }
16390 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016391 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016392
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053016394 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016395 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
16396 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016397
Hoonki Leea34dd892013-02-05 22:56:02 -080016398 /*Except teardown responder will not be used so just make 0*/
16399 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016400 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080016401 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016402
16403 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016404 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016405
16406 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
16407 responder = pTdlsPeer->is_responder;
16408 else
Hoonki Leea34dd892013-02-05 22:56:02 -080016409 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053016411 "%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 -070016412 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
16413 dialog_token, status_code, len);
16414 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080016415 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016416 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016417
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016418 /* For explicit trigger of DIS_REQ come out of BMPS for
16419 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070016420 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016421 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
16422 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070016423 {
16424 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
16425 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016427 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016428 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
16429 if (status != VOS_STATUS_SUCCESS) {
16430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
16431 }
Hoonki Lee14621352013-04-16 17:51:19 -070016432 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016433 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016434 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
16436 }
16437 }
Hoonki Lee14621352013-04-16 17:51:19 -070016438 }
16439
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016440 /* make sure doesn't call send_mgmt() while it is pending */
16441 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
16442 {
16443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016444 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016445 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016446 ret = -EBUSY;
16447 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016448 }
16449
16450 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016451 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
16452
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016453 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
16454 pAdapter->sessionId, peer, action_code, dialog_token,
16455 status_code, peer_capability, (tANI_U8 *)buf, len,
16456 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016457
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016458 if (VOS_STATUS_SUCCESS != status)
16459 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16461 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016462 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016463 ret = -EINVAL;
16464 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016465 }
16466
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016467 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
16468 (SIR_MAC_TDLS_DIS_RSP == action_code))
16469 {
16470 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
16471 * So we no need to wait for tdls_mgmt_comp for sending ack status.
16472 */
16473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16474 "%s: tx done for frm %u", __func__, action_code);
16475 return 0;
16476 }
16477
16478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16479 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
16480 WAIT_TIME_TDLS_MGMT);
16481
Hoonki Leed37cbb32013-04-20 00:31:14 -070016482 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
16483 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
16484
16485 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016486 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070016487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016488 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070016489 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016490 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080016491
16492 if (pHddCtx->isLogpInProgress)
16493 {
16494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16495 "%s: LOGP in Progress. Ignore!!!", __func__);
16496 return -EAGAIN;
16497 }
Abhishek Singh837adf22015-10-01 17:37:37 +053016498 if (rc <= 0)
16499 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
16500 WLAN_LOG_INDICATOR_HOST_DRIVER,
16501 WLAN_LOG_REASON_HDD_TIME_OUT,
16502 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080016503
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016504 ret = -EINVAL;
16505 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016506 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016507 else
16508 {
16509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16510 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
16511 __func__, rc, pAdapter->mgmtTxCompletionStatus);
16512 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016513
Gopichand Nakkala05922802013-03-14 12:23:19 -070016514 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070016515 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016516 ret = max_sta_failed;
16517 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070016518 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016519
Hoonki Leea34dd892013-02-05 22:56:02 -080016520 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
16521 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016522 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16524 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016525 }
16526 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
16527 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016528 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16530 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016531 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016532
16533 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016534
16535tx_failed:
16536 /* add_station will be called before sending TDLS_SETUP_REQ and
16537 * TDLS_SETUP_RSP and as part of add_station driver will enable
16538 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
16539 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
16540 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
16541 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
16542 */
16543
16544 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
16545 (SIR_MAC_TDLS_SETUP_RSP == action_code))
16546 wlan_hdd_tdls_check_bmps(pAdapter);
16547 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016548}
16549
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016550#if TDLS_MGMT_VERSION2
16551static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16552 u8 *peer, u8 action_code, u8 dialog_token,
16553 u16 status_code, u32 peer_capability,
16554 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016555#else /* TDLS_MGMT_VERSION2 */
16556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16557static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16558 struct net_device *dev,
16559 const u8 *peer, u8 action_code,
16560 u8 dialog_token, u16 status_code,
16561 u32 peer_capability, bool initiator,
16562 const u8 *buf, size_t len)
16563#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16564static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16565 struct net_device *dev,
16566 const u8 *peer, u8 action_code,
16567 u8 dialog_token, u16 status_code,
16568 u32 peer_capability, const u8 *buf,
16569 size_t len)
16570#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16571static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16572 struct net_device *dev,
16573 u8 *peer, u8 action_code,
16574 u8 dialog_token,
16575 u16 status_code, u32 peer_capability,
16576 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016577#else
16578static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16579 u8 *peer, u8 action_code, u8 dialog_token,
16580 u16 status_code, const u8 *buf, size_t len)
16581#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016582#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016583{
16584 int ret;
16585
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016586 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016587#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016588 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16589 dialog_token, status_code,
16590 peer_capability, buf, len);
16591#else /* TDLS_MGMT_VERSION2 */
16592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16593 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16594 dialog_token, status_code,
16595 peer_capability, initiator,
16596 buf, len);
16597#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16598 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16599 dialog_token, status_code,
16600 peer_capability, buf, len);
16601#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16602 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16603 dialog_token, status_code,
16604 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016605#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016606 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16607 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016608#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016609#endif
16610 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016611
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016612 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016613}
Atul Mittal115287b2014-07-08 13:26:33 +053016614
16615int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16617 const u8 *peer,
16618#else
Atul Mittal115287b2014-07-08 13:26:33 +053016619 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016620#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016621 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016622 cfg80211_exttdls_callback callback)
16623{
16624
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016625 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016626 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016627 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16629 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16630 __func__, MAC_ADDR_ARRAY(peer));
16631
16632 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16633 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16634
16635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016636 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16637 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16638 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016639 return -ENOTSUPP;
16640 }
16641
16642 /* To cater the requirement of establishing the TDLS link
16643 * irrespective of the data traffic , get an entry of TDLS peer.
16644 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016645 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016646 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16647 if (pTdlsPeer == NULL) {
16648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16649 "%s: peer " MAC_ADDRESS_STR " not existing",
16650 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016651 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016652 return -EINVAL;
16653 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016654 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016655
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016656 /* check FW TDLS Off Channel capability */
16657 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016658 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016659 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016660 {
16661 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16662 pTdlsPeer->peerParams.global_operating_class =
16663 tdls_peer_params->global_operating_class;
16664 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16665 pTdlsPeer->peerParams.min_bandwidth_kbps =
16666 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016667 /* check configured channel is valid, non dfs and
16668 * not current operating channel */
16669 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16670 tdls_peer_params->channel)) &&
16671 (pHddStaCtx) &&
16672 (tdls_peer_params->channel !=
16673 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016674 {
16675 pTdlsPeer->isOffChannelConfigured = TRUE;
16676 }
16677 else
16678 {
16679 pTdlsPeer->isOffChannelConfigured = FALSE;
16680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16681 "%s: Configured Tdls Off Channel is not valid", __func__);
16682
16683 }
16684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016685 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16686 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016687 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016688 pTdlsPeer->isOffChannelConfigured,
16689 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016690 }
16691 else
16692 {
16693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016694 "%s: TDLS off channel FW capability %d, "
16695 "host capab %d or Invalid TDLS Peer Params", __func__,
16696 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16697 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016698 }
16699
Atul Mittal115287b2014-07-08 13:26:33 +053016700 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16701
16702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16703 " %s TDLS Add Force Peer Failed",
16704 __func__);
16705 return -EINVAL;
16706 }
16707 /*EXT TDLS*/
16708
16709 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16711 " %s TDLS set callback Failed",
16712 __func__);
16713 return -EINVAL;
16714 }
16715
16716 return(0);
16717
16718}
16719
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016720int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16721#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16722 const u8 *peer
16723#else
16724 u8 *peer
16725#endif
16726)
Atul Mittal115287b2014-07-08 13:26:33 +053016727{
16728
16729 hddTdlsPeer_t *pTdlsPeer;
16730 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16732 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16733 __func__, MAC_ADDR_ARRAY(peer));
16734
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016735 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16737 return -EINVAL;
16738 }
16739
Atul Mittal115287b2014-07-08 13:26:33 +053016740 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16741 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16742
16743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016744 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16745 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16746 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016747 return -ENOTSUPP;
16748 }
16749
16750
16751 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16752
16753 if ( NULL == pTdlsPeer ) {
16754 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016755 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016756 __func__, MAC_ADDR_ARRAY(peer));
16757 return -EINVAL;
16758 }
16759 else {
16760 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16761 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016762 /* if channel switch is configured, reset
16763 the channel for this peer */
16764 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16765 {
16766 pTdlsPeer->peerParams.channel = 0;
16767 pTdlsPeer->isOffChannelConfigured = FALSE;
16768 }
Atul Mittal115287b2014-07-08 13:26:33 +053016769 }
16770
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016771 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016773 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016774 }
Atul Mittal115287b2014-07-08 13:26:33 +053016775
16776 /*EXT TDLS*/
16777
16778 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16779
16780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16781 " %s TDLS set callback Failed",
16782 __func__);
16783 return -EINVAL;
16784 }
16785 return(0);
16786
16787}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016788static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016789#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16790 const u8 *peer,
16791#else
16792 u8 *peer,
16793#endif
16794 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016795{
16796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16797 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016798 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016799 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016800
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016801 ENTER();
16802
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016803 if (!pAdapter) {
16804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16805 return -EINVAL;
16806 }
16807
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016808 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16809 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16810 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016811 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016812 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016814 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016815 return -EINVAL;
16816 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016817
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016818 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016819 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016820 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016821 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016822 }
16823
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016824
16825 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016826 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016827 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016829 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16830 "Cannot process TDLS commands",
16831 pHddCtx->cfg_ini->fEnableTDLSSupport,
16832 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016833 return -ENOTSUPP;
16834 }
16835
16836 switch (oper) {
16837 case NL80211_TDLS_ENABLE_LINK:
16838 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016839 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016840 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016841 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016842 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016843 tANI_U16 numCurrTdlsPeers = 0;
16844 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016845 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016846
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16848 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16849 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016850 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016851 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016852 if ( NULL == pTdlsPeer ) {
16853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16854 " (oper %d) not exsting. ignored",
16855 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16856 return -EINVAL;
16857 }
16858
16859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16860 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16861 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16862 "NL80211_TDLS_ENABLE_LINK");
16863
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016864 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16865 {
16866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16867 MAC_ADDRESS_STR " failed",
16868 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16869 return -EINVAL;
16870 }
16871
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016872 /* before starting tdls connection, set tdls
16873 * off channel established status to default value */
16874 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016875 /* TDLS Off Channel, Disable tdls channel switch,
16876 when there are more than one tdls link */
16877 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016878 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016879 {
16880 /* get connected peer and send disable tdls off chan */
16881 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016882 if ((connPeer) &&
16883 (connPeer->isOffChannelSupported == TRUE) &&
16884 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016885 {
16886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16887 "%s: More then one peer connected, Disable "
16888 "TDLS channel switch", __func__);
16889
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016890 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016891 ret = sme_SendTdlsChanSwitchReq(
16892 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016893 pAdapter->sessionId,
16894 connPeer->peerMac,
16895 connPeer->peerParams.channel,
16896 TDLS_OFF_CHANNEL_BW_OFFSET,
16897 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016898 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016899 hddLog(VOS_TRACE_LEVEL_ERROR,
16900 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016901 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016902 }
16903 else
16904 {
16905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16906 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016907 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016908 "isOffChannelConfigured %d",
16909 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016910 (connPeer ? (connPeer->isOffChannelSupported)
16911 : -1),
16912 (connPeer ? (connPeer->isOffChannelConfigured)
16913 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016914 }
16915 }
16916
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016917 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016918 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016919 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016920
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016921 if (0 != wlan_hdd_tdls_get_link_establish_params(
16922 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016924 return -EINVAL;
16925 }
16926 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016927
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016928 ret = sme_SendTdlsLinkEstablishParams(
16929 WLAN_HDD_GET_HAL_CTX(pAdapter),
16930 pAdapter->sessionId, peer,
16931 &tdlsLinkEstablishParams);
16932 if (ret != VOS_STATUS_SUCCESS) {
16933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16934 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016935 /* Send TDLS peer UAPSD capabilities to the firmware and
16936 * register with the TL on after the response for this operation
16937 * is received .
16938 */
16939 ret = wait_for_completion_interruptible_timeout(
16940 &pAdapter->tdls_link_establish_req_comp,
16941 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16942 if (ret <= 0)
16943 {
16944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016945 FL("Link Establish Request Failed Status %ld"),
16946 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016947 return -EINVAL;
16948 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016949 }
Atul Mittal115287b2014-07-08 13:26:33 +053016950 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16951 eTDLS_LINK_CONNECTED,
16952 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016953 staDesc.ucSTAId = pTdlsPeer->staId;
16954 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016955 ret = WLANTL_UpdateTdlsSTAClient(
16956 pHddCtx->pvosContext,
16957 &staDesc);
16958 if (ret != VOS_STATUS_SUCCESS) {
16959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16960 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016961
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016962 /* Mark TDLS client Authenticated .*/
16963 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16964 pTdlsPeer->staId,
16965 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016966 if (VOS_STATUS_SUCCESS == status)
16967 {
Hoonki Lee14621352013-04-16 17:51:19 -070016968 if (pTdlsPeer->is_responder == 0)
16969 {
16970 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016971 tdlsConnInfo_t *tdlsInfo;
16972
16973 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16974
16975 /* Initialize initiator wait callback */
16976 vos_timer_init(
16977 &pTdlsPeer->initiatorWaitTimeoutTimer,
16978 VOS_TIMER_TYPE_SW,
16979 wlan_hdd_tdls_initiator_wait_cb,
16980 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016981
16982 wlan_hdd_tdls_timer_restart(pAdapter,
16983 &pTdlsPeer->initiatorWaitTimeoutTimer,
16984 WAIT_TIME_TDLS_INITIATOR);
16985 /* suspend initiator TX until it receives direct packet from the
16986 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016987 ret = WLANTL_SuspendDataTx(
16988 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16989 &staId, NULL);
16990 if (ret != VOS_STATUS_SUCCESS) {
16991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16992 }
Hoonki Lee14621352013-04-16 17:51:19 -070016993 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016994
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016995 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016996 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016997 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016998 suppChannelLen =
16999 tdlsLinkEstablishParams.supportedChannelsLen;
17000
17001 if ((suppChannelLen > 0) &&
17002 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17003 {
17004 tANI_U8 suppPeerChannel = 0;
17005 int i = 0;
17006 for (i = 0U; i < suppChannelLen; i++)
17007 {
17008 suppPeerChannel =
17009 tdlsLinkEstablishParams.supportedChannels[i];
17010
17011 pTdlsPeer->isOffChannelSupported = FALSE;
17012 if (suppPeerChannel ==
17013 pTdlsPeer->peerParams.channel)
17014 {
17015 pTdlsPeer->isOffChannelSupported = TRUE;
17016 break;
17017 }
17018 }
17019 }
17020 else
17021 {
17022 pTdlsPeer->isOffChannelSupported = FALSE;
17023 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017024 }
17025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17026 "%s: TDLS channel switch request for channel "
17027 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017028 "%d isOffChannelSupported %d", __func__,
17029 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017030 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017031 suppChannelLen,
17032 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017033
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017034 /* TDLS Off Channel, Enable tdls channel switch,
17035 when their is only one tdls link and it supports */
17036 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17037 if ((numCurrTdlsPeers == 1) &&
17038 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17039 (TRUE == pTdlsPeer->isOffChannelConfigured))
17040 {
17041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17042 "%s: Send TDLS channel switch request for channel %d",
17043 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017044
17045 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017046 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17047 pAdapter->sessionId,
17048 pTdlsPeer->peerMac,
17049 pTdlsPeer->peerParams.channel,
17050 TDLS_OFF_CHANNEL_BW_OFFSET,
17051 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017052 if (ret != VOS_STATUS_SUCCESS) {
17053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17054 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017055 }
17056 else
17057 {
17058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17059 "%s: TDLS channel switch request not sent"
17060 " numCurrTdlsPeers %d "
17061 "isOffChannelSupported %d "
17062 "isOffChannelConfigured %d",
17063 __func__, numCurrTdlsPeers,
17064 pTdlsPeer->isOffChannelSupported,
17065 pTdlsPeer->isOffChannelConfigured);
17066 }
17067
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017068 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017069 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017070
17071 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017072 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
17073 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017074 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017075 int ac;
17076 uint8 ucAc[4] = { WLANTL_AC_VO,
17077 WLANTL_AC_VI,
17078 WLANTL_AC_BK,
17079 WLANTL_AC_BE };
17080 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
17081 for(ac=0; ac < 4; ac++)
17082 {
17083 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17084 pTdlsPeer->staId, ucAc[ac],
17085 tlTid[ac], tlTid[ac], 0, 0,
17086 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017087 if (status != VOS_STATUS_SUCCESS) {
17088 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
17089 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017090 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017091 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017092 }
17093
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017094 }
17095 break;
17096 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080017097 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017098 tANI_U16 numCurrTdlsPeers = 0;
17099 hddTdlsPeer_t *connPeer = NULL;
17100
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17102 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
17103 __func__, MAC_ADDR_ARRAY(peer));
17104
Sunil Dutt41de4e22013-11-14 18:09:02 +053017105 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
17106
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017107
Sunil Dutt41de4e22013-11-14 18:09:02 +053017108 if ( NULL == pTdlsPeer ) {
17109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17110 " (oper %d) not exsting. ignored",
17111 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17112 return -EINVAL;
17113 }
17114
17115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17116 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17117 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17118 "NL80211_TDLS_DISABLE_LINK");
17119
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017120 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080017121 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017122 long status;
17123
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017124 /* set tdls off channel status to false for this peer */
17125 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053017126 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17127 eTDLS_LINK_TEARING,
17128 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
17129 eTDLS_LINK_UNSPECIFIED:
17130 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017131 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
17132
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017133 status = sme_DeleteTdlsPeerSta(
17134 WLAN_HDD_GET_HAL_CTX(pAdapter),
17135 pAdapter->sessionId, peer );
17136 if (status != VOS_STATUS_SUCCESS) {
17137 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17138 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017139
17140 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
17141 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053017142 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053017143 eTDLS_LINK_IDLE,
17144 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017145 if (status <= 0)
17146 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17148 "%s: Del station failed status %ld",
17149 __func__, status);
17150 return -EPERM;
17151 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017152
17153 /* TDLS Off Channel, Enable tdls channel switch,
17154 when their is only one tdls link and it supports */
17155 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17156 if (numCurrTdlsPeers == 1)
17157 {
17158 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
17159 if ((connPeer) &&
17160 (connPeer->isOffChannelSupported == TRUE) &&
17161 (connPeer->isOffChannelConfigured == TRUE))
17162 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017163 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017164 status = sme_SendTdlsChanSwitchReq(
17165 WLAN_HDD_GET_HAL_CTX(pAdapter),
17166 pAdapter->sessionId,
17167 connPeer->peerMac,
17168 connPeer->peerParams.channel,
17169 TDLS_OFF_CHANNEL_BW_OFFSET,
17170 TDLS_CHANNEL_SWITCH_ENABLE);
17171 if (status != VOS_STATUS_SUCCESS) {
17172 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
17173 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017174 }
17175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17176 "%s: TDLS channel switch "
17177 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017178 "isOffChannelConfigured %d "
17179 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017180 __func__,
17181 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017182 (connPeer ? connPeer->isOffChannelConfigured : -1),
17183 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017184 }
17185 else
17186 {
17187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17188 "%s: TDLS channel switch request not sent "
17189 "numCurrTdlsPeers %d ",
17190 __func__, numCurrTdlsPeers);
17191 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017192 }
17193 else
17194 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17196 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080017197 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017198 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017199 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017200 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053017201 {
Atul Mittal115287b2014-07-08 13:26:33 +053017202 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017203
Atul Mittal115287b2014-07-08 13:26:33 +053017204 if (0 != status)
17205 {
17206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017207 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053017208 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053017209 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053017210 break;
17211 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017212 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053017213 {
Atul Mittal115287b2014-07-08 13:26:33 +053017214 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
17215 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017216 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053017217 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017218
Atul Mittal115287b2014-07-08 13:26:33 +053017219 if (0 != status)
17220 {
17221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017222 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053017223 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053017224 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053017225 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053017226 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017227 case NL80211_TDLS_DISCOVERY_REQ:
17228 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017230 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017231 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017232 return -ENOTSUPP;
17233 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17235 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017236 return -ENOTSUPP;
17237 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017238
17239 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017240 return 0;
17241}
Chilam NG571c65a2013-01-19 12:27:36 +053017242
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017243static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17245 const u8 *peer,
17246#else
17247 u8 *peer,
17248#endif
17249 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017250{
17251 int ret;
17252
17253 vos_ssr_protect(__func__);
17254 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
17255 vos_ssr_unprotect(__func__);
17256
17257 return ret;
17258}
17259
Chilam NG571c65a2013-01-19 12:27:36 +053017260int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
17261 struct net_device *dev, u8 *peer)
17262{
Arif Hussaina7c8e412013-11-20 11:06:42 -080017263 hddLog(VOS_TRACE_LEVEL_INFO,
17264 "tdls send discover req: "MAC_ADDRESS_STR,
17265 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053017266
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017267#if TDLS_MGMT_VERSION2
17268 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17269 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17270#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17272 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17273 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
17274#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17275 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17276 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17277#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17278 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17279 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17280#else
Chilam NG571c65a2013-01-19 12:27:36 +053017281 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17282 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017283#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017284#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053017285}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017286#endif
17287
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017288#ifdef WLAN_FEATURE_GTK_OFFLOAD
17289/*
17290 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
17291 * Callback rountine called upon receiving response for
17292 * get offload info
17293 */
17294void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
17295 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
17296{
17297
17298 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017299 tANI_U8 tempReplayCounter[8];
17300 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017301
17302 ENTER();
17303
17304 if (NULL == pAdapter)
17305 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017307 "%s: HDD adapter is Null", __func__);
17308 return ;
17309 }
17310
17311 if (NULL == pGtkOffloadGetInfoRsp)
17312 {
17313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17314 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
17315 return ;
17316 }
17317
17318 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
17319 {
17320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17321 "%s: wlan Failed to get replay counter value",
17322 __func__);
17323 return ;
17324 }
17325
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017326 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17327 /* Update replay counter */
17328 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
17329 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17330
17331 {
17332 /* changing from little to big endian since supplicant
17333 * works on big endian format
17334 */
17335 int i;
17336 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17337
17338 for (i = 0; i < 8; i++)
17339 {
17340 tempReplayCounter[7-i] = (tANI_U8)p[i];
17341 }
17342 }
17343
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017344 /* Update replay counter to NL */
17345 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017346 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017347}
17348
17349/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017350 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017351 * This function is used to offload GTK rekeying job to the firmware.
17352 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017353int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017354 struct cfg80211_gtk_rekey_data *data)
17355{
17356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17357 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17358 hdd_station_ctx_t *pHddStaCtx;
17359 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017360 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017361 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017362 eHalStatus status = eHAL_STATUS_FAILURE;
17363
17364 ENTER();
17365
17366 if (NULL == pAdapter)
17367 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017369 "%s: HDD adapter is Null", __func__);
17370 return -ENODEV;
17371 }
17372
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017373 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17374 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
17375 pAdapter->sessionId, pAdapter->device_mode));
17376
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017377 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017378 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017379 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017380 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017381 }
17382
17383 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17384 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17385 if (NULL == hHal)
17386 {
17387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17388 "%s: HAL context is Null!!!", __func__);
17389 return -EAGAIN;
17390 }
17391
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017392 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
17393 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
17394 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
17395 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017396 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017397 {
17398 /* changing from big to little endian since driver
17399 * works on little endian format
17400 */
17401 tANI_U8 *p =
17402 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
17403 int i;
17404
17405 for (i = 0; i < 8; i++)
17406 {
17407 p[7-i] = data->replay_ctr[i];
17408 }
17409 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017410
17411 if (TRUE == pHddCtx->hdd_wlan_suspended)
17412 {
17413 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017414 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
17415 sizeof (tSirGtkOffloadParams));
17416 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017417 pAdapter->sessionId);
17418
17419 if (eHAL_STATUS_SUCCESS != status)
17420 {
17421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17422 "%s: sme_SetGTKOffload failed, returned %d",
17423 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017424
17425 /* Need to clear any trace of key value in the memory.
17426 * Thus zero out the memory even though it is local
17427 * variable.
17428 */
17429 vos_mem_zero(&hddGtkOffloadReqParams,
17430 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017431 return status;
17432 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17434 "%s: sme_SetGTKOffload successfull", __func__);
17435 }
17436 else
17437 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17439 "%s: wlan not suspended GTKOffload request is stored",
17440 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017441 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017442
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017443 /* Need to clear any trace of key value in the memory.
17444 * Thus zero out the memory even though it is local
17445 * variable.
17446 */
17447 vos_mem_zero(&hddGtkOffloadReqParams,
17448 sizeof(hddGtkOffloadReqParams));
17449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017450 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017451 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017452}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017453
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017454int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
17455 struct cfg80211_gtk_rekey_data *data)
17456{
17457 int ret;
17458
17459 vos_ssr_protect(__func__);
17460 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
17461 vos_ssr_unprotect(__func__);
17462
17463 return ret;
17464}
17465#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017466/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017467 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017468 * This function is used to set access control policy
17469 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017470static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17471 struct net_device *dev,
17472 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017473{
17474 int i;
17475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17476 hdd_hostapd_state_t *pHostapdState;
17477 tsap_Config_t *pConfig;
17478 v_CONTEXT_t pVosContext = NULL;
17479 hdd_context_t *pHddCtx;
17480 int status;
17481
17482 ENTER();
17483
17484 if (NULL == pAdapter)
17485 {
17486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17487 "%s: HDD adapter is Null", __func__);
17488 return -ENODEV;
17489 }
17490
17491 if (NULL == params)
17492 {
17493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17494 "%s: params is Null", __func__);
17495 return -EINVAL;
17496 }
17497
17498 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17499 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017500 if (0 != status)
17501 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017502 return status;
17503 }
17504
17505 pVosContext = pHddCtx->pvosContext;
17506 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
17507
17508 if (NULL == pHostapdState)
17509 {
17510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17511 "%s: pHostapdState is Null", __func__);
17512 return -EINVAL;
17513 }
17514
17515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
17516 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017517 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17518 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
17519 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017520
17521 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
17522 {
17523 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
17524
17525 /* default value */
17526 pConfig->num_accept_mac = 0;
17527 pConfig->num_deny_mac = 0;
17528
17529 /**
17530 * access control policy
17531 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
17532 * listed in hostapd.deny file.
17533 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
17534 * listed in hostapd.accept file.
17535 */
17536 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
17537 {
17538 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
17539 }
17540 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
17541 {
17542 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
17543 }
17544 else
17545 {
17546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17547 "%s:Acl Policy : %d is not supported",
17548 __func__, params->acl_policy);
17549 return -ENOTSUPP;
17550 }
17551
17552 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
17553 {
17554 pConfig->num_accept_mac = params->n_acl_entries;
17555 for (i = 0; i < params->n_acl_entries; i++)
17556 {
17557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17558 "** Add ACL MAC entry %i in WhiletList :"
17559 MAC_ADDRESS_STR, i,
17560 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17561
17562 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17563 sizeof(qcmacaddr));
17564 }
17565 }
17566 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17567 {
17568 pConfig->num_deny_mac = params->n_acl_entries;
17569 for (i = 0; i < params->n_acl_entries; i++)
17570 {
17571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17572 "** Add ACL MAC entry %i in BlackList :"
17573 MAC_ADDRESS_STR, i,
17574 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17575
17576 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17577 sizeof(qcmacaddr));
17578 }
17579 }
17580
17581 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17582 {
17583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17584 "%s: SAP Set Mac Acl fail", __func__);
17585 return -EINVAL;
17586 }
17587 }
17588 else
17589 {
17590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017591 "%s: Invalid device_mode = %s (%d)",
17592 __func__, hdd_device_modetoString(pAdapter->device_mode),
17593 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017594 return -EINVAL;
17595 }
17596
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017597 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017598 return 0;
17599}
17600
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017601static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17602 struct net_device *dev,
17603 const struct cfg80211_acl_data *params)
17604{
17605 int ret;
17606 vos_ssr_protect(__func__);
17607 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17608 vos_ssr_unprotect(__func__);
17609
17610 return ret;
17611}
17612
Leo Chang9056f462013-08-01 19:21:11 -070017613#ifdef WLAN_NL80211_TESTMODE
17614#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017615void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017616(
17617 void *pAdapter,
17618 void *indCont
17619)
17620{
Leo Changd9df8aa2013-09-26 13:32:26 -070017621 tSirLPHBInd *lphbInd;
17622 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017623 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017624
17625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017626 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017627
c_hpothu73f35e62014-04-18 13:40:08 +053017628 if (pAdapter == NULL)
17629 {
17630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17631 "%s: pAdapter is NULL\n",__func__);
17632 return;
17633 }
17634
Leo Chang9056f462013-08-01 19:21:11 -070017635 if (NULL == indCont)
17636 {
17637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017638 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017639 return;
17640 }
17641
c_hpothu73f35e62014-04-18 13:40:08 +053017642 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017643 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017644 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017645 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017646 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017647 GFP_ATOMIC);
17648 if (!skb)
17649 {
17650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17651 "LPHB timeout, NL buffer alloc fail");
17652 return;
17653 }
17654
Leo Changac3ba772013-10-07 09:47:04 -070017655 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017656 {
17657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17658 "WLAN_HDD_TM_ATTR_CMD put fail");
17659 goto nla_put_failure;
17660 }
Leo Changac3ba772013-10-07 09:47:04 -070017661 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017662 {
17663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17664 "WLAN_HDD_TM_ATTR_TYPE put fail");
17665 goto nla_put_failure;
17666 }
Leo Changac3ba772013-10-07 09:47:04 -070017667 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017668 sizeof(tSirLPHBInd), lphbInd))
17669 {
17670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17671 "WLAN_HDD_TM_ATTR_DATA put fail");
17672 goto nla_put_failure;
17673 }
Leo Chang9056f462013-08-01 19:21:11 -070017674 cfg80211_testmode_event(skb, GFP_ATOMIC);
17675 return;
17676
17677nla_put_failure:
17678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17679 "NLA Put fail");
17680 kfree_skb(skb);
17681
17682 return;
17683}
17684#endif /* FEATURE_WLAN_LPHB */
17685
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017686static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017687{
17688 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17689 int err = 0;
17690#ifdef FEATURE_WLAN_LPHB
17691 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017692 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017693
17694 ENTER();
17695
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017696 err = wlan_hdd_validate_context(pHddCtx);
17697 if (0 != err)
17698 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017699 return err;
17700 }
Leo Chang9056f462013-08-01 19:21:11 -070017701#endif /* FEATURE_WLAN_LPHB */
17702
17703 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17704 if (err)
17705 {
17706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17707 "%s Testmode INV ATTR", __func__);
17708 return err;
17709 }
17710
17711 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17712 {
17713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17714 "%s Testmode INV CMD", __func__);
17715 return -EINVAL;
17716 }
17717
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017718 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17719 TRACE_CODE_HDD_CFG80211_TESTMODE,
17720 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017721 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17722 {
17723#ifdef FEATURE_WLAN_LPHB
17724 /* Low Power Heartbeat configuration request */
17725 case WLAN_HDD_TM_CMD_WLAN_HB:
17726 {
17727 int buf_len;
17728 void *buf;
17729 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017730 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017731
17732 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17733 {
17734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17735 "%s Testmode INV DATA", __func__);
17736 return -EINVAL;
17737 }
17738
17739 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17740 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017741
17742 hb_params_temp =(tSirLPHBReq *)buf;
17743 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17744 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17745 return -EINVAL;
17746
Leo Chang9056f462013-08-01 19:21:11 -070017747 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17748 if (NULL == hb_params)
17749 {
17750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17751 "%s Request Buffer Alloc Fail", __func__);
17752 return -EINVAL;
17753 }
17754
17755 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017756 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17757 hb_params,
17758 wlan_hdd_cfg80211_lphb_ind_handler);
17759 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017760 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17762 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017763 vos_mem_free(hb_params);
17764 }
Leo Chang9056f462013-08-01 19:21:11 -070017765 return 0;
17766 }
17767#endif /* FEATURE_WLAN_LPHB */
17768 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17770 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017771 return -EOPNOTSUPP;
17772 }
17773
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017774 EXIT();
17775 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017776}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017777
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017778static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17779#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17780 struct wireless_dev *wdev,
17781#endif
17782 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017783{
17784 int ret;
17785
17786 vos_ssr_protect(__func__);
17787 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17788 vos_ssr_unprotect(__func__);
17789
17790 return ret;
17791}
Leo Chang9056f462013-08-01 19:21:11 -070017792#endif /* CONFIG_NL80211_TESTMODE */
17793
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017794static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017795 struct net_device *dev,
17796 int idx, struct survey_info *survey)
17797{
17798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17799 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017800 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017801 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017802 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017803 v_S7_t snr,rssi;
17804 int status, i, j, filled = 0;
17805
17806 ENTER();
17807
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017808 if (NULL == pAdapter)
17809 {
17810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17811 "%s: HDD adapter is Null", __func__);
17812 return -ENODEV;
17813 }
17814
17815 if (NULL == wiphy)
17816 {
17817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17818 "%s: wiphy is Null", __func__);
17819 return -ENODEV;
17820 }
17821
17822 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17823 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017824 if (0 != status)
17825 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017826 return status;
17827 }
17828
Mihir Sheted9072e02013-08-21 17:02:29 +053017829 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17830
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017831 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017832 0 != pAdapter->survey_idx ||
17833 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017834 {
17835 /* The survey dump ops when implemented completely is expected to
17836 * return a survey of all channels and the ops is called by the
17837 * kernel with incremental values of the argument 'idx' till it
17838 * returns -ENONET. But we can only support the survey for the
17839 * operating channel for now. survey_idx is used to track
17840 * that the ops is called only once and then return -ENONET for
17841 * the next iteration
17842 */
17843 pAdapter->survey_idx = 0;
17844 return -ENONET;
17845 }
17846
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017847 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17848 {
17849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17850 "%s: Roaming in progress, hence return ", __func__);
17851 return -ENONET;
17852 }
17853
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017854 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17855
17856 wlan_hdd_get_snr(pAdapter, &snr);
17857 wlan_hdd_get_rssi(pAdapter, &rssi);
17858
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17860 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17861 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017862 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17863 hdd_wlan_get_freq(channel, &freq);
17864
17865
17866 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17867 {
17868 if (NULL == wiphy->bands[i])
17869 {
17870 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17871 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17872 continue;
17873 }
17874
17875 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17876 {
17877 struct ieee80211_supported_band *band = wiphy->bands[i];
17878
17879 if (band->channels[j].center_freq == (v_U16_t)freq)
17880 {
17881 survey->channel = &band->channels[j];
17882 /* The Rx BDs contain SNR values in dB for the received frames
17883 * while the supplicant expects noise. So we calculate and
17884 * return the value of noise (dBm)
17885 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17886 */
17887 survey->noise = rssi - snr;
17888 survey->filled = SURVEY_INFO_NOISE_DBM;
17889 filled = 1;
17890 }
17891 }
17892 }
17893
17894 if (filled)
17895 pAdapter->survey_idx = 1;
17896 else
17897 {
17898 pAdapter->survey_idx = 0;
17899 return -ENONET;
17900 }
17901
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017902 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017903 return 0;
17904}
17905
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017906static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17907 struct net_device *dev,
17908 int idx, struct survey_info *survey)
17909{
17910 int ret;
17911
17912 vos_ssr_protect(__func__);
17913 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17914 vos_ssr_unprotect(__func__);
17915
17916 return ret;
17917}
17918
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017919/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017920 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017921 * this is called when cfg80211 driver resume
17922 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17923 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017924int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017925{
17926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17927 hdd_adapter_t *pAdapter;
17928 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17929 VOS_STATUS status = VOS_STATUS_SUCCESS;
17930
17931 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017932
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017933 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017934 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017935 return 0;
17936 }
17937
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017938 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17939 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017940 spin_lock(&pHddCtx->schedScan_lock);
17941 pHddCtx->isWiphySuspended = FALSE;
17942 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17943 {
17944 spin_unlock(&pHddCtx->schedScan_lock);
17945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17946 "%s: Return resume is not due to PNO indication", __func__);
17947 return 0;
17948 }
17949 // Reset flag to avoid updatating cfg80211 data old results again
17950 pHddCtx->isSchedScanUpdatePending = FALSE;
17951 spin_unlock(&pHddCtx->schedScan_lock);
17952
17953 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17954
17955 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17956 {
17957 pAdapter = pAdapterNode->pAdapter;
17958 if ( (NULL != pAdapter) &&
17959 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17960 {
17961 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017962 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17964 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017965 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017966 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017967 {
17968 /* Acquire wakelock to handle the case where APP's tries to
17969 * suspend immediately after updating the scan results. Whis
17970 * results in app's is in suspended state and not able to
17971 * process the connect request to AP
17972 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017973 hdd_prevent_suspend_timeout(2000,
17974 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017975 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017976 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017977
17978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17979 "%s : cfg80211 scan result database updated", __func__);
17980
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017981 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017982 return 0;
17983
17984 }
17985 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17986 pAdapterNode = pNext;
17987 }
17988
17989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17990 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017991 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017992 return 0;
17993}
17994
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017995int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17996{
17997 int ret;
17998
17999 vos_ssr_protect(__func__);
18000 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18001 vos_ssr_unprotect(__func__);
18002
18003 return ret;
18004}
18005
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018006/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018007 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018008 * this is called when cfg80211 driver suspends
18009 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018010int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018011 struct cfg80211_wowlan *wow)
18012{
18013 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018014 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018015
18016 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018017
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018018 ret = wlan_hdd_validate_context(pHddCtx);
18019 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018020 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018021 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018022 }
18023
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018024
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018025 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18026 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18027 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018028 pHddCtx->isWiphySuspended = TRUE;
18029
18030 EXIT();
18031
18032 return 0;
18033}
18034
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018035int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
18036 struct cfg80211_wowlan *wow)
18037{
18038 int ret;
18039
18040 vos_ssr_protect(__func__);
18041 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
18042 vos_ssr_unprotect(__func__);
18043
18044 return ret;
18045}
Jeff Johnson295189b2012-06-20 16:38:30 -070018046/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018047static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070018048{
18049 .add_virtual_intf = wlan_hdd_add_virtual_intf,
18050 .del_virtual_intf = wlan_hdd_del_virtual_intf,
18051 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
18052 .change_station = wlan_hdd_change_station,
18053#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
18054 .add_beacon = wlan_hdd_cfg80211_add_beacon,
18055 .del_beacon = wlan_hdd_cfg80211_del_beacon,
18056 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018057#else
18058 .start_ap = wlan_hdd_cfg80211_start_ap,
18059 .change_beacon = wlan_hdd_cfg80211_change_beacon,
18060 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070018061#endif
18062 .change_bss = wlan_hdd_cfg80211_change_bss,
18063 .add_key = wlan_hdd_cfg80211_add_key,
18064 .get_key = wlan_hdd_cfg80211_get_key,
18065 .del_key = wlan_hdd_cfg80211_del_key,
18066 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018067#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070018068 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018069#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018070 .scan = wlan_hdd_cfg80211_scan,
18071 .connect = wlan_hdd_cfg80211_connect,
18072 .disconnect = wlan_hdd_cfg80211_disconnect,
18073 .join_ibss = wlan_hdd_cfg80211_join_ibss,
18074 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
18075 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
18076 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
18077 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070018078 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
18079 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053018080 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070018081#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18082 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
18083 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
18084 .set_txq_params = wlan_hdd_set_txq_params,
18085#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018086 .get_station = wlan_hdd_cfg80211_get_station,
18087 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
18088 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018089 .add_station = wlan_hdd_cfg80211_add_station,
18090#ifdef FEATURE_WLAN_LFR
18091 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
18092 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
18093 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
18094#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018095#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
18096 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
18097#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018098#ifdef FEATURE_WLAN_TDLS
18099 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
18100 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
18101#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018102#ifdef WLAN_FEATURE_GTK_OFFLOAD
18103 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
18104#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018105#ifdef FEATURE_WLAN_SCAN_PNO
18106 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
18107 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
18108#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018109 .resume = wlan_hdd_cfg80211_resume_wlan,
18110 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018111 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070018112#ifdef WLAN_NL80211_TESTMODE
18113 .testmode_cmd = wlan_hdd_cfg80211_testmode,
18114#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018115 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070018116};
18117