blob: d9b36464c2ab811458bbb9cf754cb2632f691bbb [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530176static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700177{
178 WLAN_CIPHER_SUITE_WEP40,
179 WLAN_CIPHER_SUITE_WEP104,
180 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700182#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
183 WLAN_CIPHER_SUITE_KRK,
184 WLAN_CIPHER_SUITE_CCMP,
185#else
186 WLAN_CIPHER_SUITE_CCMP,
187#endif
188#ifdef FEATURE_WLAN_WAPI
189 WLAN_CIPHER_SUITE_SMS4,
190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700191#ifdef WLAN_FEATURE_11W
192 WLAN_CIPHER_SUITE_AES_CMAC,
193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700194};
195
196static inline int is_broadcast_ether_addr(const u8 *addr)
197{
198 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
199 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
200}
201
202static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530203{
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD2GHZCHAN(2412, 1, 0) ,
205 HDD2GHZCHAN(2417, 2, 0) ,
206 HDD2GHZCHAN(2422, 3, 0) ,
207 HDD2GHZCHAN(2427, 4, 0) ,
208 HDD2GHZCHAN(2432, 5, 0) ,
209 HDD2GHZCHAN(2437, 6, 0) ,
210 HDD2GHZCHAN(2442, 7, 0) ,
211 HDD2GHZCHAN(2447, 8, 0) ,
212 HDD2GHZCHAN(2452, 9, 0) ,
213 HDD2GHZCHAN(2457, 10, 0) ,
214 HDD2GHZCHAN(2462, 11, 0) ,
215 HDD2GHZCHAN(2467, 12, 0) ,
216 HDD2GHZCHAN(2472, 13, 0) ,
217 HDD2GHZCHAN(2484, 14, 0) ,
218};
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
221{
222 HDD2GHZCHAN(2412, 1, 0) ,
223 HDD2GHZCHAN(2437, 6, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225};
Jeff Johnson295189b2012-06-20 16:38:30 -0700226
227static struct ieee80211_channel hdd_channels_5_GHZ[] =
228{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700229 HDD5GHZCHAN(4920, 240, 0) ,
230 HDD5GHZCHAN(4940, 244, 0) ,
231 HDD5GHZCHAN(4960, 248, 0) ,
232 HDD5GHZCHAN(4980, 252, 0) ,
233 HDD5GHZCHAN(5040, 208, 0) ,
234 HDD5GHZCHAN(5060, 212, 0) ,
235 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 HDD5GHZCHAN(5180, 36, 0) ,
237 HDD5GHZCHAN(5200, 40, 0) ,
238 HDD5GHZCHAN(5220, 44, 0) ,
239 HDD5GHZCHAN(5240, 48, 0) ,
240 HDD5GHZCHAN(5260, 52, 0) ,
241 HDD5GHZCHAN(5280, 56, 0) ,
242 HDD5GHZCHAN(5300, 60, 0) ,
243 HDD5GHZCHAN(5320, 64, 0) ,
244 HDD5GHZCHAN(5500,100, 0) ,
245 HDD5GHZCHAN(5520,104, 0) ,
246 HDD5GHZCHAN(5540,108, 0) ,
247 HDD5GHZCHAN(5560,112, 0) ,
248 HDD5GHZCHAN(5580,116, 0) ,
249 HDD5GHZCHAN(5600,120, 0) ,
250 HDD5GHZCHAN(5620,124, 0) ,
251 HDD5GHZCHAN(5640,128, 0) ,
252 HDD5GHZCHAN(5660,132, 0) ,
253 HDD5GHZCHAN(5680,136, 0) ,
254 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800255#ifdef FEATURE_WLAN_CH144
256 HDD5GHZCHAN(5720,144, 0) ,
257#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 HDD5GHZCHAN(5745,149, 0) ,
259 HDD5GHZCHAN(5765,153, 0) ,
260 HDD5GHZCHAN(5785,157, 0) ,
261 HDD5GHZCHAN(5805,161, 0) ,
262 HDD5GHZCHAN(5825,165, 0) ,
263};
264
265static struct ieee80211_rate g_mode_rates[] =
266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530267 HDD_G_MODE_RATETAB(10, 0x1, 0),
268 HDD_G_MODE_RATETAB(20, 0x2, 0),
269 HDD_G_MODE_RATETAB(55, 0x4, 0),
270 HDD_G_MODE_RATETAB(110, 0x8, 0),
271 HDD_G_MODE_RATETAB(60, 0x10, 0),
272 HDD_G_MODE_RATETAB(90, 0x20, 0),
273 HDD_G_MODE_RATETAB(120, 0x40, 0),
274 HDD_G_MODE_RATETAB(180, 0x80, 0),
275 HDD_G_MODE_RATETAB(240, 0x100, 0),
276 HDD_G_MODE_RATETAB(360, 0x200, 0),
277 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530279};
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281static struct ieee80211_rate a_mode_rates[] =
282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283 HDD_G_MODE_RATETAB(60, 0x10, 0),
284 HDD_G_MODE_RATETAB(90, 0x20, 0),
285 HDD_G_MODE_RATETAB(120, 0x40, 0),
286 HDD_G_MODE_RATETAB(180, 0x80, 0),
287 HDD_G_MODE_RATETAB(240, 0x100, 0),
288 HDD_G_MODE_RATETAB(360, 0x200, 0),
289 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 HDD_G_MODE_RATETAB(540, 0x800, 0),
291};
292
293static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
294{
295 .channels = hdd_channels_2_4_GHZ,
296 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
297 .band = IEEE80211_BAND_2GHZ,
298 .bitrates = g_mode_rates,
299 .n_bitrates = g_mode_rates_size,
300 .ht_cap.ht_supported = 1,
301 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
302 | IEEE80211_HT_CAP_GRN_FLD
303 | IEEE80211_HT_CAP_DSSSCCK40
304 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
305 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
306 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
307 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
308 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
309 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
310};
311
Jeff Johnson295189b2012-06-20 16:38:30 -0700312static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
313{
314 .channels = hdd_social_channels_2_4_GHZ,
315 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
316 .band = IEEE80211_BAND_2GHZ,
317 .bitrates = g_mode_rates,
318 .n_bitrates = g_mode_rates_size,
319 .ht_cap.ht_supported = 1,
320 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
321 | IEEE80211_HT_CAP_GRN_FLD
322 | IEEE80211_HT_CAP_DSSSCCK40
323 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
324 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
325 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
326 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
327 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
328 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
329};
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
331static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
332{
333 .channels = hdd_channels_5_GHZ,
334 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
335 .band = IEEE80211_BAND_5GHZ,
336 .bitrates = a_mode_rates,
337 .n_bitrates = a_mode_rates_size,
338 .ht_cap.ht_supported = 1,
339 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
340 | IEEE80211_HT_CAP_GRN_FLD
341 | IEEE80211_HT_CAP_DSSSCCK40
342 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
343 | IEEE80211_HT_CAP_SGI_40
344 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
345 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
346 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
347 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
348 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
349 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
350};
351
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530352/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 TX/RX direction for each kind of interface */
354static const struct ieee80211_txrx_stypes
355wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
356 [NL80211_IFTYPE_STATION] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ACTION) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ),
360 },
361 [NL80211_IFTYPE_AP] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_PROBE_REQ) |
366 BIT(SIR_MAC_MGMT_DISASSOC) |
367 BIT(SIR_MAC_MGMT_AUTH) |
368 BIT(SIR_MAC_MGMT_DEAUTH) |
369 BIT(SIR_MAC_MGMT_ACTION),
370 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 [NL80211_IFTYPE_ADHOC] = {
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 [NL80211_IFTYPE_P2P_CLIENT] = {
382 .tx = 0xffff,
383 .rx = BIT(SIR_MAC_MGMT_ACTION) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ),
385 },
386 [NL80211_IFTYPE_P2P_GO] = {
387 /* This is also same as for SoftAP */
388 .tx = 0xffff,
389 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
391 BIT(SIR_MAC_MGMT_PROBE_REQ) |
392 BIT(SIR_MAC_MGMT_DISASSOC) |
393 BIT(SIR_MAC_MGMT_AUTH) |
394 BIT(SIR_MAC_MGMT_DEAUTH) |
395 BIT(SIR_MAC_MGMT_ACTION),
396 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700397};
398
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400static const struct ieee80211_iface_limit
401wlan_hdd_iface_limit[] = {
402 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /* max = 3 ; Our driver create two interfaces during driver init
404 * wlan0 and p2p0 interfaces. p2p0 is considered as station
405 * interface until a group is formed. In JB architecture, once the
406 * group is formed, interface type of p2p0 is changed to P2P GO or
407 * Client.
408 * When supplicant remove the group, it first issue a set interface
409 * cmd to change the mode back to Station. In JB this works fine as
410 * we advertize two station type interface during driver init.
411 * Some vendors create separate interface for P2P GO/Client,
412 * after group formation(Third one). But while group remove
413 * supplicant first tries to change the mode(3rd interface) to STATION
414 * But as we advertized only two sta type interfaces nl80211 was
415 * returning error for the third one which was leading to failure in
416 * delete interface. Ideally while removing the group, supplicant
417 * should not try to change the 3rd interface mode to Station type.
418 * Till we get a fix in wpa_supplicant, we advertize max STA
419 * interface type to 3
420 */
421 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422 .types = BIT(NL80211_IFTYPE_STATION),
423 },
424 {
425 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700426 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 },
428 {
429 .max = 1,
430 .types = BIT(NL80211_IFTYPE_P2P_GO) |
431 BIT(NL80211_IFTYPE_P2P_CLIENT),
432 },
433};
434
435/* By default, only single channel concurrency is allowed */
436static struct ieee80211_iface_combination
437wlan_hdd_iface_combination = {
438 .limits = wlan_hdd_iface_limit,
439 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800440 /*
441 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
442 * and p2p0 interfaces during driver init
443 * Some vendors create separate interface for P2P operations.
444 * wlan0: STA interface
445 * p2p0: P2P Device interface, action frames goes
446 * through this interface.
447 * p2p-xx: P2P interface, After GO negotiation this interface is
448 * created for p2p operations(GO/CLIENT interface).
449 */
450 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800451 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
452 .beacon_int_infra_match = false,
453};
454#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456static struct cfg80211_ops wlan_hdd_cfg80211_ops;
457
458/* Data rate 100KBPS based on IE Index */
459struct index_data_rate_type
460{
461 v_U8_t beacon_rate_index;
462 v_U16_t supported_rate[4];
463};
464
465/* 11B, 11G Rate table include Basic rate and Extended rate
466 The IDX field is the rate index
467 The HI field is the rate when RSSI is strong or being ignored
468 (in this case we report actual rate)
469 The MID field is the rate when RSSI is moderate
470 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
471 The LO field is the rate when RSSI is low
472 (in this case we don't report rates, actual current rate used)
473 */
474static const struct
475{
476 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700478} supported_data_rate[] =
479{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480/* IDX HI HM LM LO (RSSI-based index */
481 {2, { 10, 10, 10, 0}},
482 {4, { 20, 20, 10, 0}},
483 {11, { 55, 20, 10, 0}},
484 {12, { 60, 55, 20, 0}},
485 {18, { 90, 55, 20, 0}},
486 {22, {110, 55, 20, 0}},
487 {24, {120, 90, 60, 0}},
488 {36, {180, 120, 60, 0}},
489 {44, {220, 180, 60, 0}},
490 {48, {240, 180, 90, 0}},
491 {66, {330, 180, 90, 0}},
492 {72, {360, 240, 90, 0}},
493 {96, {480, 240, 120, 0}},
494 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700495};
496
497/* MCS Based rate table */
498static struct index_data_rate_type supported_mcs_rate[] =
499{
500/* MCS L20 L40 S20 S40 */
501 {0, {65, 135, 72, 150}},
502 {1, {130, 270, 144, 300}},
503 {2, {195, 405, 217, 450}},
504 {3, {260, 540, 289, 600}},
505 {4, {390, 810, 433, 900}},
506 {5, {520, 1080, 578, 1200}},
507 {6, {585, 1215, 650, 1350}},
508 {7, {650, 1350, 722, 1500}}
509};
510
Leo Chang6f8870f2013-03-26 18:11:36 -0700511#ifdef WLAN_FEATURE_11AC
512
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530513#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700514
515struct index_vht_data_rate_type
516{
517 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518 v_U16_t supported_VHT80_rate[2];
519 v_U16_t supported_VHT40_rate[2];
520 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700521};
522
523typedef enum
524{
525 DATA_RATE_11AC_MAX_MCS_7,
526 DATA_RATE_11AC_MAX_MCS_8,
527 DATA_RATE_11AC_MAX_MCS_9,
528 DATA_RATE_11AC_MAX_MCS_NA
529} eDataRate11ACMaxMcs;
530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530531/* SSID broadcast type */
532typedef enum eSSIDBcastType
533{
534 eBCAST_UNKNOWN = 0,
535 eBCAST_NORMAL = 1,
536 eBCAST_HIDDEN = 2,
537} tSSIDBcastType;
538
Leo Chang6f8870f2013-03-26 18:11:36 -0700539/* MCS Based VHT rate table */
540static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
541{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542/* MCS L80 S80 L40 S40 L20 S40*/
543 {0, {293, 325}, {135, 150}, {65, 72}},
544 {1, {585, 650}, {270, 300}, {130, 144}},
545 {2, {878, 975}, {405, 450}, {195, 217}},
546 {3, {1170, 1300}, {540, 600}, {260, 289}},
547 {4, {1755, 1950}, {810, 900}, {390, 433}},
548 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
549 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
550 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
551 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
552 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700553};
554#endif /* WLAN_FEATURE_11AC */
555
c_hpothu79aab322014-07-14 21:11:01 +0530556/*array index points to MCS and array value points respective rssi*/
557static int rssiMcsTbl[][10] =
558{
559/*MCS 0 1 2 3 4 5 6 7 8 9*/
560 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
561 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
562 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
563};
564
Jeff Johnson295189b2012-06-20 16:38:30 -0700565extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530566#ifdef FEATURE_WLAN_SCAN_PNO
567static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
626 NULL,
627#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648/*
649 * FUNCTION: __wlan_hdd_cfg80211_nan_request
650 * This is called when wlan driver needs to send vendor specific
651 * nan request event.
652 */
653static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
654 struct wireless_dev *wdev,
655 const void *data, int data_len)
656{
657 tNanRequestReq nan_req;
658 VOS_STATUS status;
659 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530660 struct net_device *dev = wdev->netdev;
661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
662 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
664
665 if (0 == data_len)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, length = 0"));
669 return ret_val;
670 }
671
672 if (NULL == data)
673 {
674 hddLog(VOS_TRACE_LEVEL_ERROR,
675 FL("NAN - Invalid Request, data is NULL"));
676 return ret_val;
677 }
678
679 status = wlan_hdd_validate_context(pHddCtx);
680 if (0 != status)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("HDD context is not valid"));
684 return -EINVAL;
685 }
686
687 hddLog(LOG1, FL("Received NAN command"));
688 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
689 (tANI_U8 *)data, data_len);
690
691 /* check the NAN Capability */
692 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR,
695 FL("NAN is not supported by Firmware"));
696 return -EINVAL;
697 }
698
699 nan_req.request_data_len = data_len;
700 nan_req.request_data = data;
701
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530702 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530703 if (VOS_STATUS_SUCCESS == status)
704 {
705 ret_val = 0;
706 }
707 return ret_val;
708}
709
710/*
711 * FUNCTION: wlan_hdd_cfg80211_nan_request
712 * Wrapper to protect the nan vendor command from ssr
713 */
714static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
715 struct wireless_dev *wdev,
716 const void *data, int data_len)
717{
718 int ret;
719
720 vos_ssr_protect(__func__);
721 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
722 vos_ssr_unprotect(__func__);
723
724 return ret;
725}
726
727/*
728 * FUNCTION: wlan_hdd_cfg80211_nan_callback
729 * This is a callback function and it gets called
730 * when we need to report nan response event to
731 * upper layers.
732 */
733static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
734{
735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
736 struct sk_buff *vendor_event;
737 int status;
738 tSirNanEvent *data;
739
740 ENTER();
741 if (NULL == msg)
742 {
743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
744 FL(" msg received here is null"));
745 return;
746 }
747 data = msg;
748
749 status = wlan_hdd_validate_context(pHddCtx);
750
751 if (0 != status)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("HDD context is not valid"));
755 return;
756 }
757
758 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
760 NULL,
761#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530762 data->event_data_len +
763 NLMSG_HDRLEN,
764 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
765 GFP_KERNEL);
766
767 if (!vendor_event)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("cfg80211_vendor_event_alloc failed"));
771 return;
772 }
773 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
774 data->event_data_len, data->event_data))
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
778 kfree_skb(vendor_event);
779 return;
780 }
781 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
782 EXIT();
783}
784
785/*
786 * FUNCTION: wlan_hdd_cfg80211_nan_init
787 * This function is called to register the callback to sme layer
788 */
789inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
790{
791 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
792}
793
794
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795#ifdef WLAN_FEATURE_LINK_LAYER_STATS
796
797static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
798 struct sk_buff *vendor_event)
799{
800 if (nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
802 stats->rate.preamble) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
805 stats->rate.nss) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
808 stats->rate.bw) ||
809 nla_put_u8(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
811 stats->rate.rateMcsIdx) ||
812 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
813 stats->rate.bitrate ) ||
814 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
815 stats->txMpdu ) ||
816 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
817 stats->rxMpdu ) ||
818 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
819 stats->mpduLost ) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
821 stats->retries) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
824 stats->retriesShort ) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
827 stats->retriesLong))
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,
830 FL("QCA_WLAN_VENDOR_ATTR put fail"));
831 return FALSE;
832 }
833 return TRUE;
834}
835
836static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
837 struct sk_buff *vendor_event)
838{
839 u32 i = 0;
840 struct nlattr *rateInfo;
841 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
842 stats->type) ||
843 nla_put(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
845 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
848 stats->capabilities) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
851 stats->numRate))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 goto error;
856 }
857
858 rateInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rateInfo)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862 for (i = 0; i < stats->numRate; i++)
863 {
864 struct nlattr *rates;
865 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
866 stats->rateStats +
867 (i * sizeof(tSirWifiRateStat)));
868 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530869 if(!rates)
870 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530871
872 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
875 FL("QCA_WLAN_VENDOR_ATTR put fail"));
876 return FALSE;
877 }
878 nla_nest_end(vendor_event, rates);
879 }
880 nla_nest_end(vendor_event, rateInfo);
881
882 return TRUE;
883error:
884 return FALSE;
885}
886
887static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
888 struct sk_buff *vendor_event)
889{
890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
891 stats->ac ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
894 stats->txMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
897 stats->rxMpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
900 stats->txMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
903 stats->rxMcast ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
906 stats->rxAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
909 stats->txAmpdu ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
912 stats->mpduLost )||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
915 stats->retries ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
918 stats->retriesShort ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
921 stats->retriesLong ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
924 stats->contentionTimeMin ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
927 stats->contentionTimeMax ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
930 stats->contentionTimeAvg ) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
933 stats->contentionNumSamples ))
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR,
936 FL("QCA_WLAN_VENDOR_ATTR put fail") );
937 return FALSE;
938 }
939 return TRUE;
940}
941
942static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
943 struct sk_buff *vendor_event)
944{
Dino Myclec8f3f332014-07-21 16:48:27 +0530945 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
949 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
952 stats->state ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
955 stats->roaming ) ||
956 nla_put_u32(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
958 stats->capabilities ) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
961 strlen(stats->ssid), stats->ssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
964 WNI_CFG_BSSID_LEN, stats->bssid) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
968 nla_put(vendor_event,
969 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
970 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
971 )
972 {
973 hddLog(VOS_TRACE_LEVEL_ERROR,
974 FL("QCA_WLAN_VENDOR_ATTR put fail") );
975 return FALSE;
976 }
977 return TRUE;
978}
979
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
981 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530982 struct sk_buff *vendor_event)
983{
984 int i = 0;
985 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
987 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530988 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 if (FALSE == put_wifi_interface_info(
991 &pWifiIfaceStat->info,
992 vendor_event))
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR,
995 FL("QCA_WLAN_VENDOR_ATTR put fail") );
996 return FALSE;
997
998 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530999 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1000 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1001 if (NULL == pWifiIfaceStatTL)
1002 {
1003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1004 return FALSE;
1005 }
1006
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301007 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1011
1012 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301016
1017 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1018 {
1019 if (VOS_STATUS_SUCCESS ==
1020 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1021 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1022 {
1023 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1024 * obtained from TL structure
1025 */
1026
1027 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1028 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048
Srinivas Dasari98947432014-11-07 19:41:24 +05301049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1050 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1052 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1054 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1056 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301057 }
1058 else
1059 {
1060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1061 }
1062
Dino Mycle3b9536d2014-07-09 22:05:24 +05301063 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1065 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1070 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1071 }
1072 else
1073 {
1074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1075 }
1076
1077
Sunil Duttc69bccb2014-05-26 21:30:20 +05301078
1079 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1082 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1084 pWifiIfaceStat->beaconRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1087 pWifiIfaceStat->mgmtRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1090 pWifiIfaceStat->mgmtActionRx) ||
1091 nla_put_u32(vendor_event,
1092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1093 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1096 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1099 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1102 pWifiIfaceStat->rssiAck))
1103 {
1104 hddLog(VOS_TRACE_LEVEL_ERROR,
1105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
1110 wmmInfo = nla_nest_start(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301112 if(!wmmInfo)
1113 {
1114 vos_mem_free(pWifiIfaceStatTL);
1115 return FALSE;
1116 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301117 for (i = 0; i < WIFI_AC_MAX; i++)
1118 {
1119 struct nlattr *wmmStats;
1120 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301121 if(!wmmStats)
1122 {
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301126 if (FALSE == put_wifi_wmm_ac_stat(
1127 &pWifiIfaceStat->AccessclassStats[i],
1128 vendor_event))
1129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR,
1131 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301132 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301133 return FALSE;
1134 }
1135
1136 nla_nest_end(vendor_event, wmmStats);
1137 }
1138 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301139 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301140 return TRUE;
1141}
1142
1143static tSirWifiInterfaceMode
1144 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1145{
1146 switch (deviceMode)
1147 {
1148 case WLAN_HDD_INFRA_STATION:
1149 return WIFI_INTERFACE_STA;
1150 case WLAN_HDD_SOFTAP:
1151 return WIFI_INTERFACE_SOFTAP;
1152 case WLAN_HDD_P2P_CLIENT:
1153 return WIFI_INTERFACE_P2P_CLIENT;
1154 case WLAN_HDD_P2P_GO:
1155 return WIFI_INTERFACE_P2P_GO;
1156 case WLAN_HDD_IBSS:
1157 return WIFI_INTERFACE_IBSS;
1158 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301159 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 }
1161}
1162
1163static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1164 tpSirWifiInterfaceInfo pInfo)
1165{
1166 v_U8_t *staMac = NULL;
1167 hdd_station_ctx_t *pHddStaCtx;
1168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1169 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1170
1171 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1172
1173 vos_mem_copy(pInfo->macAddr,
1174 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1175
1176 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1178 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1179 {
1180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1181 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1182 {
1183 pInfo->state = WIFI_DISCONNECTED;
1184 }
1185 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1186 {
1187 hddLog(VOS_TRACE_LEVEL_ERROR,
1188 "%s: Session ID %d, Connection is in progress", __func__,
1189 pAdapter->sessionId);
1190 pInfo->state = WIFI_ASSOCIATING;
1191 }
1192 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1193 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1194 {
1195 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: client " MAC_ADDRESS_STR
1198 " is in the middle of WPS/EAPOL exchange.", __func__,
1199 MAC_ADDR_ARRAY(staMac));
1200 pInfo->state = WIFI_AUTHENTICATING;
1201 }
1202 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_ASSOCIATED;
1205 vos_mem_copy(pInfo->bssid,
1206 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1207 vos_mem_copy(pInfo->ssid,
1208 pHddStaCtx->conn_info.SSID.SSID.ssId,
1209 pHddStaCtx->conn_info.SSID.SSID.length);
1210 //NULL Terminate the string.
1211 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1212 }
1213 }
1214 vos_mem_copy(pInfo->countryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 vos_mem_copy(pInfo->apCountryStr,
1218 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1219
1220 return TRUE;
1221}
1222
1223/*
1224 * hdd_link_layer_process_peer_stats () - This function is called after
1225 * receiving Link Layer Peer statistics from FW.This function converts
1226 * the firmware data to the NL data and sends the same to the kernel/upper
1227 * layers.
1228 */
1229static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1230 v_VOID_t *pData)
1231{
1232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 tpSirWifiPeerStat pWifiPeerStat;
1234 tpSirWifiPeerInfo pWifiPeerInfo;
1235 struct nlattr *peerInfo;
1236 struct sk_buff *vendor_event;
1237 int status, i;
1238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301239 ENTER();
1240
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 status = wlan_hdd_validate_context(pHddCtx);
1242 if (0 != status)
1243 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244 return;
1245 }
1246
1247 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "LL_STATS_PEER_ALL : numPeers %u",
1251 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301252 /*
1253 * Allocate a size of 4096 for the peer stats comprising
1254 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1255 * sizeof (tSirWifiRateStat).Each field is put with an
1256 * NL attribute.The size of 4096 is considered assuming
1257 * that number of rates shall not exceed beyond 50 with
1258 * the sizeof (tSirWifiRateStat) being 32.
1259 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301260 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1261 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 if (!vendor_event)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301265 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 __func__);
1267 return;
1268 }
1269 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1271 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1272 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1274 pWifiPeerStat->numPeers))
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1278 kfree_skb(vendor_event);
1279 return;
1280 }
1281
1282 peerInfo = nla_nest_start(vendor_event,
1283 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301284 if(!peerInfo)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1288 __func__);
1289 kfree_skb(vendor_event);
1290 return;
1291 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301292
1293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1294 pWifiPeerStat->peerInfo);
1295
1296 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1297 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301299 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301301 if(!peers)
1302 {
1303 hddLog(VOS_TRACE_LEVEL_ERROR,
1304 "%s: peer stats put fail",
1305 __func__);
1306 kfree_skb(vendor_event);
1307 return;
1308 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 if (FALSE == put_wifi_peer_info(
1310 pWifiPeerInfo, vendor_event))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: put_wifi_peer_info put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo +
1320 (i * sizeof(tSirWifiPeerInfo)) +
1321 (numRate * sizeof (tSirWifiRateStat)));
1322 nla_nest_end(vendor_event, peers);
1323 }
1324 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301325 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301326 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327}
1328
1329/*
1330 * hdd_link_layer_process_iface_stats () - This function is called after
1331 * receiving Link Layer Interface statistics from FW.This function converts
1332 * the firmware data to the NL data and sends the same to the kernel/upper
1333 * layers.
1334 */
1335static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1336 v_VOID_t *pData)
1337{
1338 tpSirWifiIfaceStat pWifiIfaceStat;
1339 struct sk_buff *vendor_event;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 int status;
1342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301343 ENTER();
1344
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 status = wlan_hdd_validate_context(pHddCtx);
1346 if (0 != status)
1347 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348 return;
1349 }
1350 /*
1351 * Allocate a size of 4096 for the interface stats comprising
1352 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1353 * assuming that all these fit with in the limit.Please take
1354 * a call on the limit based on the data requirements on
1355 * interface statistics.
1356 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301357 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1358 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 if (!vendor_event)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301362 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 return;
1364 }
1365
1366 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1367
Dino Mycle3b9536d2014-07-09 22:05:24 +05301368
1369 if (FALSE == hdd_get_interface_info( pAdapter,
1370 &pWifiIfaceStat->info))
1371 {
1372 hddLog(VOS_TRACE_LEVEL_ERROR,
1373 FL("hdd_get_interface_info get fail") );
1374 kfree_skb(vendor_event);
1375 return;
1376 }
1377
1378 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1379 vendor_event))
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 FL("put_wifi_iface_stats fail") );
1383 kfree_skb(vendor_event);
1384 return;
1385 }
1386
Sunil Duttc69bccb2014-05-26 21:30:20 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
1388 "WMI_LINK_STATS_IFACE Data");
1389
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301390 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 if (!vendor_event)
1448 {
1449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 return;
1452 }
1453
1454 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1457 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
Sunil Duttc69bccb2014-05-26 21:30:20 +05301515 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301516 if(!chInfo)
1517 {
1518 hddLog(VOS_TRACE_LEVEL_ERROR,
1519 "%s: failed to put chInfo",
1520 __func__);
1521 kfree_skb(vendor_event);
1522 return;
1523 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524
1525 if (nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1527 pWifiChannelStats->channel.width) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1530 pWifiChannelStats->channel.centerFreq) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1533 pWifiChannelStats->channel.centerFreq0) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1536 pWifiChannelStats->channel.centerFreq1) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1539 pWifiChannelStats->onTime) ||
1540 nla_put_u32(vendor_event,
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1542 pWifiChannelStats->ccaBusyTime))
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 FL("cfg80211_vendor_event_alloc failed") );
1546 kfree_skb(vendor_event);
1547 return ;
1548 }
1549 nla_nest_end(vendor_event, chInfo);
1550 }
1551 nla_nest_end(vendor_event, chList);
1552
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301553 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301554
1555 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 return;
1557}
1558
1559/*
1560 * hdd_link_layer_stats_ind_callback () - This function is called after
1561 * receiving Link Layer indications from FW.This callback converts the firmware
1562 * data to the NL data and send the same to the kernel/upper layers.
1563 */
1564static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1565 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301566 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567{
Dino Mycled3d50022014-07-07 12:58:25 +05301568 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1569 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301570 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301571 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 int status;
1573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301576 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 if (0 != status)
1578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580 }
1581
Dino Mycled3d50022014-07-07 12:58:25 +05301582 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1583 if (NULL == pAdapter)
1584 {
1585 hddLog(VOS_TRACE_LEVEL_ERROR,
1586 FL(" MAC address %pM does not exist with host"),
1587 macAddr);
1588 return;
1589 }
1590
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "%s: Interface: %s LLStats indType: %d", __func__,
1593 pAdapter->dev->name, indType);
1594
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 switch (indType)
1596 {
1597 case SIR_HAL_LL_STATS_RESULTS_RSP:
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301600 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1601 "respId = %u, moreResultToFollow = %u",
1602 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1603 macAddr, linkLayerStatsResults->respId,
1604 linkLayerStatsResults->moreResultToFollow);
1605
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 spin_lock(&hdd_context_lock);
1607 context = &pHddCtx->ll_stats_context;
1608 /* validate response received from target */
1609 if ((context->request_id != linkLayerStatsResults->respId) ||
1610 !(context->request_bitmap & linkLayerStatsResults->paramId))
1611 {
1612 spin_unlock(&hdd_context_lock);
1613 hddLog(LOGE,
1614 FL("Error : Request id %d response id %d request bitmap 0x%x"
1615 "response bitmap 0x%x"),
1616 context->request_id, linkLayerStatsResults->respId,
1617 context->request_bitmap, linkLayerStatsResults->paramId);
1618 return;
1619 }
1620 spin_unlock(&hdd_context_lock);
1621
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1623 {
1624 hdd_link_layer_process_radio_stats(pAdapter,
1625 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1628 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 }
1630 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1631 {
1632 hdd_link_layer_process_iface_stats(pAdapter,
1633 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301634 spin_lock(&hdd_context_lock);
1635 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1636 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 }
1638 else if ( linkLayerStatsResults->paramId &
1639 WMI_LINK_STATS_ALL_PEER )
1640 {
1641 hdd_link_layer_process_peer_stats(pAdapter,
1642 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301643 spin_lock(&hdd_context_lock);
1644 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1645 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646 } /* WMI_LINK_STATS_ALL_PEER */
1647 else
1648 {
1649 hddLog(VOS_TRACE_LEVEL_ERROR,
1650 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1651 }
1652
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301653 spin_lock(&hdd_context_lock);
1654 /* complete response event if all requests are completed */
1655 if (0 == context->request_bitmap)
1656 complete(&context->response_event);
1657 spin_unlock(&hdd_context_lock);
1658
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 break;
1660 }
1661 default:
1662 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1663 break;
1664 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301665
1666 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 return;
1668}
1669
1670const struct
1671nla_policy
1672qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1673{
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1675 { .type = NLA_U32 },
1676 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1677 { .type = NLA_U32 },
1678};
1679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301680static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1681 struct wireless_dev *wdev,
1682 const void *data,
1683 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684{
1685 int status;
1686 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 struct net_device *dev = wdev->netdev;
1689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301692 ENTER();
1693
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 status = wlan_hdd_validate_context(pHddCtx);
1695 if (0 != status)
1696 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return -EINVAL;
1698 }
1699
1700 if (NULL == pAdapter)
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("HDD adapter is Null"));
1704 return -ENODEV;
1705 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 /* check the LLStats Capability */
1707 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1708 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("Link Layer Statistics not supported by Firmware"));
1712 return -EINVAL;
1713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1716 (struct nlattr *)data,
1717 data_len, qca_wlan_vendor_ll_set_policy))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1720 return -EINVAL;
1721 }
1722 if (!tb_vendor
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1726 return -EINVAL;
1727 }
1728 if (!tb_vendor[
1729 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1740
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301742 nla_get_u32(
1743 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1744
Dino Mycled3d50022014-07-07 12:58:25 +05301745 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1746 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747
1748
1749 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301750 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1751 "Statistics Gathering = %d ",
1752 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1753 linkLayerStatsSetReq.mpduSizeThreshold,
1754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1770 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771 return -EINVAL;
1772 }
1773
1774 pAdapter->isLinkLayerStatsSet = 1;
1775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301776 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 return 0;
1778}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301779static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1780 struct wireless_dev *wdev,
1781 const void *data,
1782 int data_len)
1783{
1784 int ret = 0;
1785
1786 vos_ssr_protect(__func__);
1787 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1788 vos_ssr_unprotect(__func__);
1789
1790 return ret;
1791}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792
1793const struct
1794nla_policy
1795qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1796{
1797 /* Unsigned 32bit value provided by the caller issuing the GET stats
1798 * command. When reporting
1799 * the stats results, the driver uses the same value to indicate
1800 * which GET request the results
1801 * correspond to.
1802 */
1803 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1804
1805 /* Unsigned 32bit value . bit mask to identify what statistics are
1806 requested for retrieval */
1807 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1808};
1809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301810static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1811 struct wireless_dev *wdev,
1812 const void *data,
1813 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301815 unsigned long rc;
1816 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 int status;
1824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301825 ENTER();
1826
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 status = wlan_hdd_validate_context(pHddCtx);
1828 if (0 != status)
1829 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 return -EINVAL ;
1831 }
1832
1833 if (NULL == pAdapter)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL,
1836 "%s: HDD adapter is Null", __func__);
1837 return -ENODEV;
1838 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301839
1840 if (pHddStaCtx == NULL)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,
1843 "%s: HddStaCtx is Null", __func__);
1844 return -ENODEV;
1845 }
1846
Dino Mycledf0a5d92014-07-04 09:41:55 +05301847 /* check the LLStats Capability */
1848 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1849 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1850 {
1851 hddLog(VOS_TRACE_LEVEL_ERROR,
1852 FL("Link Layer Statistics not supported by Firmware"));
1853 return -EINVAL;
1854 }
1855
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856
1857 if (!pAdapter->isLinkLayerStatsSet)
1858 {
1859 hddLog(VOS_TRACE_LEVEL_FATAL,
1860 "%s: isLinkLayerStatsSet : %d",
1861 __func__, pAdapter->isLinkLayerStatsSet);
1862 return -EINVAL;
1863 }
1864
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "%s: Roaming in progress, so unable to proceed this request", __func__);
1869 return -EBUSY;
1870 }
1871
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1873 (struct nlattr *)data,
1874 data_len, qca_wlan_vendor_ll_get_policy))
1875 {
1876 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1877 return -EINVAL;
1878 }
1879
1880 if (!tb_vendor
1881 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1882 {
1883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1884 return -EINVAL;
1885 }
1886
1887 if (!tb_vendor
1888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1891 return -EINVAL;
1892 }
1893
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1901
Dino Mycled3d50022014-07-07 12:58:25 +05301902 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1903 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904
1905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301906 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1907 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301910 spin_lock(&hdd_context_lock);
1911 context = &pHddCtx->ll_stats_context;
1912 context->request_id = linkLayerStatsGetReq.reqId;
1913 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1914 INIT_COMPLETION(context->response_event);
1915 spin_unlock(&hdd_context_lock);
1916
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1921 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 return -EINVAL;
1923 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301924
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301925 rc = wait_for_completion_timeout(&context->response_event,
1926 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1927 if (!rc)
1928 {
1929 hddLog(LOGE,
1930 FL("Target response timed out request id %d request bitmap 0x%x"),
1931 context->request_id, context->request_bitmap);
1932 return -ETIMEDOUT;
1933 }
1934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301935 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 return 0;
1937}
1938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301939static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1940 struct wireless_dev *wdev,
1941 const void *data,
1942 int data_len)
1943{
1944 int ret = 0;
1945
1946 vos_ssr_protect(__func__);
1947 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953const struct
1954nla_policy
1955qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1956{
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1961};
1962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301963static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1964 struct wireless_dev *wdev,
1965 const void *data,
1966 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301967{
1968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1969 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301970 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 struct net_device *dev = wdev->netdev;
1972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1973 u32 statsClearReqMask;
1974 u8 stopReq;
1975 int status;
1976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301977 ENTER();
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 status = wlan_hdd_validate_context(pHddCtx);
1980 if (0 != status)
1981 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 return -EINVAL;
1983 }
1984
1985 if (NULL == pAdapter)
1986 {
1987 hddLog(VOS_TRACE_LEVEL_FATAL,
1988 "%s: HDD adapter is Null", __func__);
1989 return -ENODEV;
1990 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 /* check the LLStats Capability */
1992 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1993 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("Enable LLStats Capability"));
1997 return -EINVAL;
1998 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999
2000 if (!pAdapter->isLinkLayerStatsSet)
2001 {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,
2003 "%s: isLinkLayerStatsSet : %d",
2004 __func__, pAdapter->isLinkLayerStatsSet);
2005 return -EINVAL;
2006 }
2007
2008 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2009 (struct nlattr *)data,
2010 data_len, qca_wlan_vendor_ll_clr_policy))
2011 {
2012 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2013 return -EINVAL;
2014 }
2015
2016 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2017
2018 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2019 {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2021 return -EINVAL;
2022
2023 }
2024
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycledf0a5d92014-07-04 09:41:55 +05302026 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 nla_get_u32(
2028 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2029
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 nla_get_u8(
2032 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2033
2034 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
Dino Mycled3d50022014-07-07 12:58:25 +05302037 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2038 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302041 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2042 "statsClearReqMask = 0x%X, stopReq = %d",
2043 linkLayerStatsClearReq.reqId,
2044 linkLayerStatsClearReq.macAddr,
2045 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047
2048 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 {
2051 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302052 hdd_station_ctx_t *pHddStaCtx;
2053
2054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2055 if (VOS_STATUS_SUCCESS !=
2056 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2057 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2060 "WLANTL_ClearInterfaceStats Failed", __func__);
2061 return -EINVAL;
2062 }
2063 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2064 (statsClearReqMask & WIFI_STATS_IFACE)) {
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2069 }
2070
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2072 2 * sizeof(u32) +
2073 NLMSG_HDRLEN);
2074
2075 if (temp_skbuff != NULL)
2076 {
2077
2078 if (nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2080 statsClearReqMask) ||
2081 nla_put_u32(temp_skbuff,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2083 stopReq))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2086 kfree_skb(temp_skbuff);
2087 return -EINVAL;
2088 }
2089 /* If the ask is to stop the stats collection as part of clear
2090 * (stopReq = 1) , ensure that no further requests of get
2091 * go to the firmware by having isLinkLayerStatsSet set to 0.
2092 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 * case the firmware is just asked to clear the statistics.
2095 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302096 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 pAdapter->isLinkLayerStatsSet = 0;
2098 return cfg80211_vendor_cmd_reply(temp_skbuff);
2099 }
2100 return -ENOMEM;
2101 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102
2103 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return -EINVAL;
2105}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302106static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2107 struct wireless_dev *wdev,
2108 const void *data,
2109 int data_len)
2110{
2111 int ret = 0;
2112
2113 vos_ssr_protect(__func__);
2114 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2115 vos_ssr_unprotect(__func__);
2116
2117 return ret;
2118
2119
2120}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2122
Dino Mycle6fb96c12014-06-10 11:52:40 +05302123#ifdef WLAN_FEATURE_EXTSCAN
2124static const struct nla_policy
2125wlan_hdd_extscan_config_policy
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2127{
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2129 { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2142 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2144 { .type = NLA_U32 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2146 { .type = NLA_U32 },
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2148 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2156 { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302158 { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2160 { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2162 { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2167 { .type = NLA_UNSPEC },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2169 { .type = NLA_S32 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2171 { .type = NLA_S32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2177 { .type = NLA_U32 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2179 { .type = NLA_BINARY,
2180 .len = IEEE80211_MAX_SSID_LEN + 1 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302182 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2184 { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2188 { .type = NLA_S32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193};
2194
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302195/**
2196 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2197 * @ctx: hdd global context
2198 * @data: capabilities data
2199 *
2200 * Return: none
2201 */
2202static void
2203wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302204{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302205 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302207 tSirEXTScanCapabilitiesEvent *data =
2208 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
2212 if (wlan_hdd_validate_context(pHddCtx))
2213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214 return;
2215 }
2216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302217 if (!pMsg)
2218 {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2220 return;
2221 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 vos_spin_lock_acquire(&hdd_context_lock);
2224
2225 context = &pHddCtx->ext_scan_context;
2226 /* validate response received from target*/
2227 if (context->request_id != data->requestId)
2228 {
2229 vos_spin_lock_release(&hdd_context_lock);
2230 hddLog(LOGE,
2231 FL("Target response id did not match: request_id %d resposne_id %d"),
2232 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302233 return;
2234 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 else
2236 {
2237 context->capability_response = *data;
2238 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239 }
2240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243 return;
2244}
2245
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302246/*
2247 * define short names for the global vendor params
2248 * used by wlan_hdd_send_ext_scan_capability()
2249 */
2250#define PARAM_REQUEST_ID \
2251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2252#define PARAM_STATUS \
2253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2254#define MAX_SCAN_CACHE_SIZE \
2255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2256#define MAX_SCAN_BUCKETS \
2257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2258#define MAX_AP_CACHE_PER_SCAN \
2259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2260#define MAX_RSSI_SAMPLE_SIZE \
2261 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2262#define MAX_SCAN_RPT_THRHOLD \
2263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2264#define MAX_HOTLIST_BSSIDS \
2265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2266#define MAX_BSSID_HISTORY_ENTRIES \
2267 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2268#define MAX_HOTLIST_SSIDS \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302270#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272
2273static int wlan_hdd_send_ext_scan_capability(void *ctx)
2274{
2275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2276 struct sk_buff *skb = NULL;
2277 int ret;
2278 tSirEXTScanCapabilitiesEvent *data;
2279 tANI_U32 nl_buf_len;
2280
2281 ret = wlan_hdd_validate_context(pHddCtx);
2282 if (0 != ret)
2283 {
2284 return ret;
2285 }
2286
2287 data = &(pHddCtx->ext_scan_context.capability_response);
2288
2289 nl_buf_len = NLMSG_HDRLEN;
2290 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2291 (sizeof(data->status) + NLA_HDRLEN) +
2292 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2293 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2294 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2295 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2296 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2297 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2298 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2299 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2300
2301 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2302
2303 if (!skb)
2304 {
2305 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2306 return -ENOMEM;
2307 }
2308
2309 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2310 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2311 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2312 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2313 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2314 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2315 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2316 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2317
2318 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2319 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2320 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2321 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2322 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2323 data->maxApPerScan) ||
2324 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2325 data->maxRssiSampleSize) ||
2326 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2327 data->maxScanReportingThreshold) ||
2328 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2329 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2330 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302331 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2332 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302333 {
2334 hddLog(LOGE, FL("nla put fail"));
2335 goto nla_put_failure;
2336 }
2337
2338 cfg80211_vendor_cmd_reply(skb);
2339 return 0;
2340
2341nla_put_failure:
2342 kfree_skb(skb);
2343 return -EINVAL;;
2344}
2345
2346/*
2347 * done with short names for the global vendor params
2348 * used by wlan_hdd_send_ext_scan_capability()
2349 */
2350#undef PARAM_REQUEST_ID
2351#undef PARAM_STATUS
2352#undef MAX_SCAN_CACHE_SIZE
2353#undef MAX_SCAN_BUCKETS
2354#undef MAX_AP_CACHE_PER_SCAN
2355#undef MAX_RSSI_SAMPLE_SIZE
2356#undef MAX_SCAN_RPT_THRHOLD
2357#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302358#undef MAX_BSSID_HISTORY_ENTRIES
2359#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302360
2361static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2362{
2363 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2364 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302365 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302366 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302369
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302370 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302371 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 if (!pMsg)
2374 {
2375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
2378
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2380 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2381
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302382 context = &pHddCtx->ext_scan_context;
2383 spin_lock(&hdd_context_lock);
2384 if (context->request_id == pData->requestId) {
2385 context->response_status = pData->status ? -EINVAL : 0;
2386 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
2390 /*
2391 * Store the Request ID for comparing with the requestID obtained
2392 * in other requests.HDD shall return a failure is the extscan_stop
2393 * request is issued with a different requestId as that of the
2394 * extscan_start request. Also, This requestId shall be used while
2395 * indicating the full scan results to the upper layers.
2396 * The requestId is stored with the assumption that the firmware
2397 * shall return the ext scan start request's requestId in ext scan
2398 * start response.
2399 */
2400 if (pData->status == 0)
2401 pMac->sme.extScanStartReqId = pData->requestId;
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405}
2406
2407
2408static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2409{
2410 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302412 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 ENTER();
2415
2416 if (wlan_hdd_validate_context(pHddCtx)){
2417 return;
2418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 if (!pMsg)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 return;
2424 }
2425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2427 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302429 context = &pHddCtx->ext_scan_context;
2430 spin_lock(&hdd_context_lock);
2431 if (context->request_id == pData->requestId) {
2432 context->response_status = pData->status ? -EINVAL : 0;
2433 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302435 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439}
2440
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2442 void *pMsg)
2443{
2444 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 tpSirEXTScanSetBssidHotListRspParams pData =
2446 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302447 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302449 ENTER();
2450
2451 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 return;
2453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 if (!pMsg)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2458 return;
2459 }
2460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2462 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302464 context = &pHddCtx->ext_scan_context;
2465 spin_lock(&hdd_context_lock);
2466 if (context->request_id == pData->requestId) {
2467 context->response_status = pData->status ? -EINVAL : 0;
2468 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302470 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302472 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474}
2475
2476static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2477 void *pMsg)
2478{
2479 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480 tpSirEXTScanResetBssidHotlistRspParams pData =
2481 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302482 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302484 ENTER();
2485
2486 if (wlan_hdd_validate_context(pHddCtx)) {
2487 return;
2488 }
2489 if (!pMsg)
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493 }
2494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2496 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302498 context = &pHddCtx->ext_scan_context;
2499 spin_lock(&hdd_context_lock);
2500 if (context->request_id == pData->requestId) {
2501 context->response_status = pData->status ? -EINVAL : 0;
2502 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302504 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302506 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302508}
2509
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302510static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2511 void *pMsg)
2512{
2513 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2514 tpSirEXTScanSetSsidHotListRspParams pData =
2515 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2516 struct hdd_ext_scan_context *context;
2517
2518 if (wlan_hdd_validate_context(pHddCtx)){
2519 return;
2520 }
2521
2522 if (!pMsg)
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2525 return;
2526 }
2527
2528 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2529 pData->status);
2530
2531 context = &pHddCtx->ext_scan_context;
2532 spin_lock(&hdd_context_lock);
2533 if (context->request_id == pData->requestId) {
2534 context->response_status = pData->status ? -EINVAL : 0;
2535 complete(&context->response_event);
2536 }
2537 spin_unlock(&hdd_context_lock);
2538
2539 return;
2540}
2541
2542static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2543 void *pMsg)
2544{
2545 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2546 tpSirEXTScanResetSsidHotlistRspParams pData =
2547 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2548 struct hdd_ext_scan_context *context;
2549
2550 if (wlan_hdd_validate_context(pHddCtx)) {
2551 return;
2552 }
2553 if (!pMsg)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2556 return;
2557 }
2558
2559 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2560 pData->status);
2561
2562 context = &pHddCtx->ext_scan_context;
2563 spin_lock(&hdd_context_lock);
2564 if (context->request_id == pData->requestId) {
2565 context->response_status = pData->status ? -EINVAL : 0;
2566 complete(&context->response_event);
2567 }
2568 spin_unlock(&hdd_context_lock);
2569
2570 return;
2571}
2572
2573
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2575 void *pMsg)
2576{
2577 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2578 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302580 tANI_S32 totalResults;
2581 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2583 struct hdd_ext_scan_context *context;
2584 bool ignore_cached_results = false;
2585 tExtscanCachedScanResult *result;
2586 struct nlattr *nla_results;
2587 tANI_U16 ieLength= 0;
2588 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 ENTER();
2591
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302592 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302593 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302595 if (!pMsg)
2596 {
2597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2598 return;
2599 }
2600
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302601 spin_lock(&hdd_context_lock);
2602 context = &pHddCtx->ext_scan_context;
2603 ignore_cached_results = context->ignore_cached_results;
2604 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302605
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302606 if (ignore_cached_results) {
2607 hddLog(LOGE,
2608 FL("Ignore the cached results received after timeout"));
2609 return;
2610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2613 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302617 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2618 scan_id_index++) {
2619 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 totalResults = result->num_results;
2622 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2623 result->scan_id, result->flags, totalResults);
2624 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 do{
2627 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2628 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2629 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2632 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2633
2634 if (!skb) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed"));
2637 return;
2638 }
2639
2640 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2641
2642 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2643 pData->requestId) ||
2644 nla_put_u32(skb,
2645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2646 resultsPerEvent)) {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2648 goto fail;
2649 }
2650 if (nla_put_u8(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2652 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302653 {
2654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2655 goto fail;
2656 }
2657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302658 if (nla_put_u32(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2660 result->scan_id)) {
2661 hddLog(LOGE, FL("put fail"));
2662 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 nla_results = nla_nest_start(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2667 if (!nla_results)
2668 goto fail;
2669
2670 if (resultsPerEvent) {
2671 struct nlattr *aps;
2672 struct nlattr *nla_result;
2673
2674 nla_result = nla_nest_start(skb, scan_id_index);
2675 if(!nla_result)
2676 goto fail;
2677
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2683 result->flags) ||
2684 nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2686 totalResults)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
2689 }
2690
2691 aps = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2693 if (!aps)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698
2699 head_ptr = (tpSirWifiScanResult) &(result->ap);
2700
2701 for (j = 0; j < resultsPerEvent; j++, i++) {
2702 struct nlattr *ap;
2703 pSirWifiScanResult = head_ptr + i;
2704
2705 /*
2706 * Firmware returns timestamp from WiFi turn ON till
2707 * BSSID was cached (in seconds). Add this with
2708 * time gap between system boot up to WiFi turn ON
2709 * to derive the time since boot when the
2710 * BSSID was cached.
2711 */
2712 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2713 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2714 "Ssid (%s)"
2715 "Bssid: %pM "
2716 "Channel (%u)"
2717 "Rssi (%d)"
2718 "RTT (%u)"
2719 "RTT_SD (%u)"
2720 "Beacon Period %u"
2721 "Capability 0x%x "
2722 "Ie length %d",
2723 i,
2724 pSirWifiScanResult->ts,
2725 pSirWifiScanResult->ssid,
2726 pSirWifiScanResult->bssid,
2727 pSirWifiScanResult->channel,
2728 pSirWifiScanResult->rssi,
2729 pSirWifiScanResult->rtt,
2730 pSirWifiScanResult->rtt_sd,
2731 pSirWifiScanResult->beaconPeriod,
2732 pSirWifiScanResult->capability,
2733 ieLength);
2734
2735 ap = nla_nest_start(skb, j + 1);
2736 if (!ap)
2737 {
2738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2739 goto fail;
2740 }
2741
2742 if (nla_put_u64(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2744 pSirWifiScanResult->ts) )
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2751 sizeof(pSirWifiScanResult->ssid),
2752 pSirWifiScanResult->ssid) )
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757 if (nla_put(skb,
2758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2759 sizeof(pSirWifiScanResult->bssid),
2760 pSirWifiScanResult->bssid) )
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2763 goto fail;
2764 }
2765 if (nla_put_u32(skb,
2766 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2767 pSirWifiScanResult->channel) )
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772 if (nla_put_s32(skb,
2773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2774 pSirWifiScanResult->rssi) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put_u32(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2781 pSirWifiScanResult->rtt) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2788 pSirWifiScanResult->rtt_sd))
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_u32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2795 pSirWifiScanResult->beaconPeriod))
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2802 pSirWifiScanResult->capability))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2809 ieLength))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (ieLength)
2816 if (nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2818 ieLength, ie)) {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822
2823 nla_nest_end(skb, ap);
2824 }
2825 nla_nest_end(skb, aps);
2826 nla_nest_end(skb, nla_result);
2827 }
2828
2829 nla_nest_end(skb, nla_results);
2830
2831 cfg80211_vendor_cmd_reply(skb);
2832
2833 } while (totalResults > 0);
2834 }
2835
2836 if (!pData->moreData) {
2837 spin_lock(&hdd_context_lock);
2838 context->response_status = 0;
2839 complete(&context->response_event);
2840 spin_unlock(&hdd_context_lock);
2841 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 return;
2845fail:
2846 kfree_skb(skb);
2847 return;
2848}
2849
2850static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2851 void *pMsg)
2852{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2855 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302856 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302858 ENTER();
2859
2860 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302861 hddLog(LOGE,
2862 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 return;
2864 }
2865 if (!pMsg)
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302868 return;
2869 }
2870
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 if (pData->bss_found)
2872 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2873 else
2874 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2875
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2878 NULL,
2879#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302882
2883 if (!skb) {
2884 hddLog(VOS_TRACE_LEVEL_ERROR,
2885 FL("cfg80211_vendor_event_alloc failed"));
2886 return;
2887 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2892 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2893
2894 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2896 "Ssid (%s) "
2897 "Bssid (" MAC_ADDRESS_STR ") "
2898 "Channel (%u) "
2899 "Rssi (%d) "
2900 "RTT (%u) "
2901 "RTT_SD (%u) ",
2902 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 pData->bssHotlist[i].ts,
2904 pData->bssHotlist[i].ssid,
2905 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2906 pData->bssHotlist[i].channel,
2907 pData->bssHotlist[i].rssi,
2908 pData->bssHotlist[i].rtt,
2909 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 }
2911
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2918 goto fail;
2919 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 struct nlattr *aps;
2922
2923 aps = nla_nest_start(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2925 if (!aps)
2926 goto fail;
2927
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302928 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 struct nlattr *ap;
2930
2931 ap = nla_nest_start(skb, i + 1);
2932 if (!ap)
2933 goto fail;
2934
2935 if (nla_put_u64(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 nla_put(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 sizeof(pData->bssHotlist[i].ssid),
2941 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302944 sizeof(pData->bssHotlist[i].bssid),
2945 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_s32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 goto fail;
2959
2960 nla_nest_end(skb, ap);
2961 }
2962 nla_nest_end(skb, aps);
2963
2964 if (nla_put_u8(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2966 pData->moreData))
2967 goto fail;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302971 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 return;
2973
2974fail:
2975 kfree_skb(skb);
2976 return;
2977
2978}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302980/**
2981 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2982 * Handle an SSID hotlist match event
2983 * @ctx: HDD context registered with SME
2984 * @event: The SSID hotlist match event
2985 *
2986 * This function will take an SSID match event that was generated by
2987 * firmware and will convert it into a cfg80211 vendor event which is
2988 * sent to userspace.
2989 *
2990 * Return: none
2991 */
2992static void
2993wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2994 void *pMsg)
2995{
2996 hdd_context_t *hdd_ctx = ctx;
2997 struct sk_buff *skb;
2998 tANI_U32 i, index;
2999 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3000
3001 ENTER();
3002
3003 if (wlan_hdd_validate_context(hdd_ctx)) {
3004 hddLog(LOGE,
3005 FL("HDD context is not valid or response"));
3006 return;
3007 }
3008 if (!pMsg)
3009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3011 return;
3012 }
3013
3014 if (pData->ssid_found) {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3016 hddLog(LOG1, "SSID hotlist found");
3017 } else {
3018 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3019 hddLog(LOG1, "SSID hotlist lost");
3020 }
3021
3022 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3024 NULL,
3025#endif
3026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3027 index, GFP_KERNEL);
3028
3029 if (!skb) {
3030 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3031 return;
3032 }
3033 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3034 pData->requestId, pData->numHotlistSsid, pData->moreData);
3035
3036 for (i = 0; i < pData->numHotlistSsid; i++) {
3037 hddLog(LOG1, "[i=%d] Timestamp %llu "
3038 "Ssid: %s "
3039 "Bssid (" MAC_ADDRESS_STR ") "
3040 "Channel %u "
3041 "Rssi %d "
3042 "RTT %u "
3043 "RTT_SD %u",
3044 i,
3045 pData->ssidHotlist[i].ts,
3046 pData->ssidHotlist[i].ssid,
3047 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3048 pData->ssidHotlist[i].channel,
3049 pData->ssidHotlist[i].rssi,
3050 pData->ssidHotlist[i].rtt,
3051 pData->ssidHotlist[i].rtt_sd);
3052 }
3053
3054 if (nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3056 pData->requestId) ||
3057 nla_put_u32(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3059 pData->numHotlistSsid)) {
3060 hddLog(LOGE, FL("put fail"));
3061 goto fail;
3062 }
3063
3064 if (pData->numHotlistSsid) {
3065 struct nlattr *aps;
3066 aps = nla_nest_start(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3068 if (!aps) {
3069 hddLog(LOGE, FL("nest fail"));
3070 goto fail;
3071 }
3072
3073 for (i = 0; i < pData->numHotlistSsid; i++) {
3074 struct nlattr *ap;
3075
3076 ap = nla_nest_start(skb, i);
3077 if (!ap) {
3078 hddLog(LOGE, FL("nest fail"));
3079 goto fail;
3080 }
3081
3082 if (nla_put_u64(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3084 pData->ssidHotlist[i].ts) ||
3085 nla_put(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3087 sizeof(pData->ssidHotlist[i].ssid),
3088 pData->ssidHotlist[i].ssid) ||
3089 nla_put(skb,
3090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3091 sizeof(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].bssid) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3095 pData->ssidHotlist[i].channel) ||
3096 nla_put_s32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3098 pData->ssidHotlist[i].rssi) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3101 pData->ssidHotlist[i].rtt) ||
3102 nla_put_u32(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3104 pData->ssidHotlist[i].rtt_sd)) {
3105 hddLog(LOGE, FL("put fail"));
3106 goto fail;
3107 }
3108 nla_nest_end(skb, ap);
3109 }
3110 nla_nest_end(skb, aps);
3111
3112 if (nla_put_u8(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3114 pData->moreData)) {
3115 hddLog(LOGE, FL("put fail"));
3116 goto fail;
3117 }
3118 }
3119
3120 cfg80211_vendor_event(skb, GFP_KERNEL);
3121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128
3129
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3131 void *pMsg)
3132{
3133 struct sk_buff *skb;
3134 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3135 tpSirWifiFullScanResultEvent pData =
3136 (tpSirWifiFullScanResultEvent) (pMsg);
3137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303138 ENTER();
3139
3140 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303141 hddLog(LOGE,
3142 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 return;
3144 }
3145 if (!pMsg)
3146 {
3147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 return;
3149 }
3150
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303151 /*
3152 * If the full scan result including IE data exceeds NL 4K size
3153 * limitation, drop that beacon/probe rsp frame.
3154 */
3155 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3156 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3157 return;
3158 }
3159
Dino Mycle6fb96c12014-06-10 11:52:40 +05303160 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3162 NULL,
3163#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3166 GFP_KERNEL);
3167
3168 if (!skb) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("cfg80211_vendor_event_alloc failed"));
3171 return;
3172 }
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3177 "Ssid (%s)"
3178 "Bssid (" MAC_ADDRESS_STR ")"
3179 "Channel (%u)"
3180 "Rssi (%d)"
3181 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 "RTT_SD (%u)"
3183 "Bcn Period %d"
3184 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 pData->ap.ts,
3186 pData->ap.ssid,
3187 MAC_ADDR_ARRAY(pData->ap.bssid),
3188 pData->ap.channel,
3189 pData->ap.rssi,
3190 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303191 pData->ap.rtt_sd,
3192 pData->ap.beaconPeriod,
3193 pData->ap.capability);
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3196 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3197 pData->requestId) ||
3198 nla_put_u64(skb,
3199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3200 pData->ap.ts) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3202 sizeof(pData->ap.ssid),
3203 pData->ap.ssid) ||
3204 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3205 WNI_CFG_BSSID_LEN,
3206 pData->ap.bssid) ||
3207 nla_put_u32(skb,
3208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3209 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303210 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 pData->ap.rssi) ||
3212 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3213 pData->ap.rtt) ||
3214 nla_put_u32(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3216 pData->ap.rtt_sd) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3219 pData->ap.beaconPeriod) ||
3220 nla_put_u16(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3222 pData->ap.capability) ||
3223 nla_put_u32(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303225 pData->ieLength) ||
3226 nla_put_u8(skb,
3227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3228 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3231 goto nla_put_failure;
3232 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303233
3234 if (pData->ieLength) {
3235 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3236 pData->ieLength,
3237 pData->ie))
3238 {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3240 goto nla_put_failure;
3241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 }
3243
3244 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246 return;
3247
3248nla_put_failure:
3249 kfree_skb(skb);
3250 return;
3251}
3252
3253static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3254 void *pMsg)
3255{
3256 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3257 struct sk_buff *skb = NULL;
3258 tpSirEXTScanResultsAvailableIndParams pData =
3259 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303261 ENTER();
3262
3263 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264 hddLog(LOGE,
3265 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 return;
3267 }
3268 if (!pMsg)
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 return;
3272 }
3273
3274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3276 NULL,
3277#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3279 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3280 GFP_KERNEL);
3281
3282 if (!skb) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("cfg80211_vendor_event_alloc failed"));
3285 return;
3286 }
3287
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3289 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3290 pData->numResultsAvailable);
3291 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3292 pData->requestId) ||
3293 nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3295 pData->numResultsAvailable)) {
3296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3297 goto nla_put_failure;
3298 }
3299
3300 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303
3304nla_put_failure:
3305 kfree_skb(skb);
3306 return;
3307}
3308
3309static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3310{
3311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3312 struct sk_buff *skb = NULL;
3313 tpSirEXTScanProgressIndParams pData =
3314 (tpSirEXTScanProgressIndParams) pMsg;
3315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303316 ENTER();
3317
3318 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303319 hddLog(LOGE,
3320 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 return;
3322 }
3323 if (!pMsg)
3324 {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
3329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3331 NULL,
3332#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3334 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3335 GFP_KERNEL);
3336
3337 if (!skb) {
3338 hddLog(VOS_TRACE_LEVEL_ERROR,
3339 FL("cfg80211_vendor_event_alloc failed"));
3340 return;
3341 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3344 pData->extScanEventType);
3345 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3346 pData->status);
3347
3348 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3349 pData->extScanEventType) ||
3350 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3352 pData->requestId) ||
3353 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3355 pData->status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3357 goto nla_put_failure;
3358 }
3359
3360 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363
3364nla_put_failure:
3365 kfree_skb(skb);
3366 return;
3367}
3368
3369void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3370 void *pMsg)
3371{
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303374 ENTER();
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 return;
3378 }
3379
3380 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3381
3382
3383 switch(evType) {
3384 case SIR_HAL_EXTSCAN_START_RSP:
3385 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3386 break;
3387
3388 case SIR_HAL_EXTSCAN_STOP_RSP:
3389 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3392 /* There is no need to send this response to upper layer
3393 Just log the message */
3394 hddLog(VOS_TRACE_LEVEL_INFO,
3395 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3396 break;
3397 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3398 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3399 break;
3400
3401 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3402 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3403 break;
3404
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303405 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3406 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3410 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3411 break;
3412
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303414 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 break;
3416 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3417 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3420 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3423 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3424 break;
3425 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3427 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303428 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3429 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3430 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3432 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3433 break;
3434 default:
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3436 break;
3437 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439}
3440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303441static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3442 struct wireless_dev *wdev,
3443 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444{
Dino Myclee8843b32014-07-04 14:21:45 +05303445 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 struct net_device *dev = wdev->netdev;
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3448 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3449 struct nlattr
3450 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3451 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452 struct hdd_ext_scan_context *context;
3453 unsigned long rc;
3454 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 ENTER();
3457
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 return -EINVAL;
3462 }
Dino Myclee8843b32014-07-04 14:21:45 +05303463 /* check the EXTScan Capability */
3464 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3465 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3466 {
3467 hddLog(VOS_TRACE_LEVEL_ERROR,
3468 FL("EXTScan not enabled/supported by Firmware"));
3469 return -EINVAL;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3473 data, dataLen,
3474 wlan_hdd_extscan_config_policy)) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3476 return -EINVAL;
3477 }
3478
3479 /* Parse and fetch request Id */
3480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3482 return -EINVAL;
3483 }
3484
Dino Myclee8843b32014-07-04 14:21:45 +05303485 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Dino Myclee8843b32014-07-04 14:21:45 +05303489 reqMsg.sessionId = pAdapter->sessionId;
3490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303492 vos_spin_lock_acquire(&hdd_context_lock);
3493 context = &pHddCtx->ext_scan_context;
3494 context->request_id = reqMsg.requestId;
3495 INIT_COMPLETION(context->response_event);
3496 vos_spin_lock_release(&hdd_context_lock);
3497
Dino Myclee8843b32014-07-04 14:21:45 +05303498 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303504
3505 rc = wait_for_completion_timeout(&context->response_event,
3506 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3507 if (!rc) {
3508 hddLog(LOGE, FL("Target response timed out"));
3509 return -ETIMEDOUT;
3510 }
3511
3512 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3513 if (ret)
3514 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3515
3516 return ret;
3517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303518 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return 0;
3520}
3521
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303522static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3523 struct wireless_dev *wdev,
3524 const void *data, int dataLen)
3525{
3526 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303528 vos_ssr_protect(__func__);
3529 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3530 vos_ssr_unprotect(__func__);
3531
3532 return ret;
3533}
3534
3535static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3536 struct wireless_dev *wdev,
3537 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538{
Dino Myclee8843b32014-07-04 14:21:45 +05303539 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 struct net_device *dev = wdev->netdev;
3541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3543 struct nlattr
3544 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3545 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 struct hdd_ext_scan_context *context;
3547 unsigned long rc;
3548 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 ENTER();
3551
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303552 if (VOS_FTM_MODE == hdd_get_conparam()) {
3553 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3554 return -EINVAL;
3555 }
3556
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 status = wlan_hdd_validate_context(pHddCtx);
3558 if (0 != status)
3559 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 return -EINVAL;
3561 }
Dino Myclee8843b32014-07-04 14:21:45 +05303562 /* check the EXTScan Capability */
3563 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3564 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 FL("EXTScan not enabled/supported by Firmware"));
3568 return -EINVAL;
3569 }
3570
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3572 data, dataLen,
3573 wlan_hdd_extscan_config_policy)) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3575 return -EINVAL;
3576 }
3577 /* Parse and fetch request Id */
3578 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3580 return -EINVAL;
3581 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582
Dino Myclee8843b32014-07-04 14:21:45 +05303583 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585
Dino Myclee8843b32014-07-04 14:21:45 +05303586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587
Dino Myclee8843b32014-07-04 14:21:45 +05303588 reqMsg.sessionId = pAdapter->sessionId;
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
3591 /* Parse and fetch flush parameter */
3592 if (!tb
3593 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3596 goto failed;
3597 }
Dino Myclee8843b32014-07-04 14:21:45 +05303598 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3600
Dino Myclee8843b32014-07-04 14:21:45 +05303601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303603 spin_lock(&hdd_context_lock);
3604 context = &pHddCtx->ext_scan_context;
3605 context->request_id = reqMsg.requestId;
3606 context->ignore_cached_results = false;
3607 INIT_COMPLETION(context->response_event);
3608 spin_unlock(&hdd_context_lock);
3609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 if (!HAL_STATUS_SUCCESS(status)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303614 return -EINVAL;
3615 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616
3617 rc = wait_for_completion_timeout(&context->response_event,
3618 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3619 if (!rc) {
3620 hddLog(LOGE, FL("Target response timed out"));
3621 retval = -ETIMEDOUT;
3622 spin_lock(&hdd_context_lock);
3623 context->ignore_cached_results = true;
3624 spin_unlock(&hdd_context_lock);
3625 } else {
3626 spin_lock(&hdd_context_lock);
3627 retval = context->response_status;
3628 spin_unlock(&hdd_context_lock);
3629 }
3630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303631 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
3634failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635 return -EINVAL;
3636}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303637static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3638 struct wireless_dev *wdev,
3639 const void *data, int dataLen)
3640{
3641 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303643 vos_ssr_protect(__func__);
3644 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3645 vos_ssr_unprotect(__func__);
3646
3647 return ret;
3648}
3649
3650static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303652 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653{
3654 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3655 struct net_device *dev = wdev->netdev;
3656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3658 struct nlattr
3659 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3660 struct nlattr
3661 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3662 struct nlattr *apTh;
3663 eHalStatus status;
3664 tANI_U8 i = 0;
3665 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303666 struct hdd_ext_scan_context *context;
3667 tANI_U32 request_id;
3668 unsigned long rc;
3669 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 ENTER();
3672
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303673 if (VOS_FTM_MODE == hdd_get_conparam()) {
3674 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3675 return -EINVAL;
3676 }
3677
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 status = wlan_hdd_validate_context(pHddCtx);
3679 if (0 != status)
3680 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3705 vos_mem_malloc(sizeof(*pReqMsg));
3706 if (!pReqMsg) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3708 return -ENOMEM;
3709 }
3710
Dino Myclee8843b32014-07-04 14:21:45 +05303711
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 pReqMsg->requestId = nla_get_u32(
3713 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3715
3716 /* Parse and fetch number of APs */
3717 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3719 goto fail;
3720 }
3721
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303722 /* Parse and fetch lost ap sample size */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3724 hddLog(LOGE, FL("attr lost ap sample size failed"));
3725 goto fail;
3726 }
3727
3728 pReqMsg->lostBssidSampleSize = nla_get_u32(
3729 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3730 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3731
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732 pReqMsg->sessionId = pAdapter->sessionId;
3733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3734
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303735 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 nla_for_each_nested(apTh,
3740 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3741 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 nla_data(apTh), nla_len(apTh),
3743 NULL)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3745 goto fail;
3746 }
3747
3748 /* Parse and fetch MAC address */
3749 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3751 goto fail;
3752 }
3753 memcpy(pReqMsg->ap[i].bssid, nla_data(
3754 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3755 sizeof(tSirMacAddr));
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3757
3758 /* Parse and fetch low RSSI */
3759 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3761 goto fail;
3762 }
3763 pReqMsg->ap[i].low = nla_get_s32(
3764 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3766
3767 /* Parse and fetch high RSSI */
3768 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3770 goto fail;
3771 }
3772 pReqMsg->ap[i].high = nla_get_s32(
3773 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3774 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3775 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776 i++;
3777 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303778
3779 context = &pHddCtx->ext_scan_context;
3780 spin_lock(&hdd_context_lock);
3781 INIT_COMPLETION(context->response_event);
3782 context->request_id = request_id = pReqMsg->requestId;
3783 spin_unlock(&hdd_context_lock);
3784
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3786 if (!HAL_STATUS_SUCCESS(status)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("sme_SetBssHotlist failed(err=%d)"), status);
3789 vos_mem_free(pReqMsg);
3790 return -EINVAL;
3791 }
3792
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303793 /* request was sent -- wait for the response */
3794 rc = wait_for_completion_timeout(&context->response_event,
3795 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3796
3797 if (!rc) {
3798 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3799 retval = -ETIMEDOUT;
3800 } else {
3801 spin_lock(&hdd_context_lock);
3802 if (context->request_id == request_id)
3803 retval = context->response_status;
3804 else
3805 retval = -EINVAL;
3806 spin_unlock(&hdd_context_lock);
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303810 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303811 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
3813fail:
3814 vos_mem_free(pReqMsg);
3815 return -EINVAL;
3816}
3817
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303818static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3819 struct wireless_dev *wdev,
3820 const void *data, int dataLen)
3821{
3822 int ret = 0;
3823
3824 vos_ssr_protect(__func__);
3825 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3826 dataLen);
3827 vos_ssr_unprotect(__func__);
3828
3829 return ret;
3830}
3831
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303832/*
3833 * define short names for the global vendor params
3834 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3835 */
3836#define PARAM_MAX \
3837QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3838#define PARAM_REQUEST_ID \
3839QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3840#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3841QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3842#define PARAMS_NUM_SSID \
3843QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3844#define THRESHOLD_PARAM \
3845QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3846#define PARAM_SSID \
3847QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3848#define PARAM_BAND \
3849QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3850#define PARAM_RSSI_LOW \
3851QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3852#define PARAM_RSSI_HIGH \
3853QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3854
3855/**
3856 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3857 * @wiphy: Pointer to wireless phy
3858 * @wdev: Pointer to wireless device
3859 * @data: Pointer to data
3860 * @data_len: Data length
3861 *
3862 * Return: 0 on success, negative errno on failure
3863 */
3864static int
3865__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data,
3868 int data_len)
3869{
3870 tSirEXTScanSetSsidHotListReqParams *request;
3871 struct net_device *dev = wdev->netdev;
3872 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3873 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3874 struct nlattr *tb[PARAM_MAX + 1];
3875 struct nlattr *tb2[PARAM_MAX + 1];
3876 struct nlattr *ssids;
3877 struct hdd_ext_scan_context *context;
3878 uint32_t request_id;
3879 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3880 int ssid_len;
3881 eHalStatus status;
3882 int i, rem, retval;
3883 unsigned long rc;
3884
3885 ENTER();
3886
3887 if (VOS_FTM_MODE == hdd_get_conparam()) {
3888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3889 return -EINVAL;
3890 }
3891
3892 retval = wlan_hdd_validate_context(hdd_ctx);
3893 if (0 != retval) {
3894 hddLog(LOGE, FL("HDD context is not valid"));
3895 return -EINVAL;
3896 }
3897
3898 /* check the EXTScan Capability */
3899 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3901 {
3902 hddLog(VOS_TRACE_LEVEL_ERROR,
3903 FL("EXTScan not enabled/supported by Firmware"));
3904 return -EINVAL;
3905 }
3906
3907 if (nla_parse(tb, PARAM_MAX,
3908 data, data_len,
3909 wlan_hdd_extscan_config_policy)) {
3910 hddLog(LOGE, FL("Invalid ATTR"));
3911 return -EINVAL;
3912 }
3913
3914 request = vos_mem_malloc(sizeof(*request));
3915 if (!request) {
3916 hddLog(LOGE, FL("vos_mem_malloc failed"));
3917 return -ENOMEM;
3918 }
3919
3920 /* Parse and fetch request Id */
3921 if (!tb[PARAM_REQUEST_ID]) {
3922 hddLog(LOGE, FL("attr request id failed"));
3923 goto fail;
3924 }
3925
3926 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3927 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3928
3929 /* Parse and fetch lost SSID sample size */
3930 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3931 hddLog(LOGE, FL("attr number of Ssid failed"));
3932 goto fail;
3933 }
3934 request->lost_ssid_sample_size =
3935 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3936 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3937 request->lost_ssid_sample_size);
3938
3939 /* Parse and fetch number of hotlist SSID */
3940 if (!tb[PARAMS_NUM_SSID]) {
3941 hddLog(LOGE, FL("attr number of Ssid failed"));
3942 goto fail;
3943 }
3944 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3945 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3946
3947 request->session_id = adapter->sessionId;
3948 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3949
3950 i = 0;
3951 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3952 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3953 hddLog(LOGE,
3954 FL("Too Many SSIDs, %d exceeds %d"),
3955 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3956 break;
3957 }
3958 if (nla_parse(tb2, PARAM_MAX,
3959 nla_data(ssids), nla_len(ssids),
3960 wlan_hdd_extscan_config_policy)) {
3961 hddLog(LOGE, FL("nla_parse failed"));
3962 goto fail;
3963 }
3964
3965 /* Parse and fetch SSID */
3966 if (!tb2[PARAM_SSID]) {
3967 hddLog(LOGE, FL("attr ssid failed"));
3968 goto fail;
3969 }
3970 nla_memcpy(ssid_string,
3971 tb2[PARAM_SSID],
3972 sizeof(ssid_string));
3973 hddLog(LOG1, FL("SSID %s"),
3974 ssid_string);
3975 ssid_len = strlen(ssid_string);
3976 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3977 request->ssid[i].ssid.length = ssid_len;
3978 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3979 hddLog(LOG1, FL("After copying SSID %s"),
3980 request->ssid[i].ssid.ssId);
3981 hddLog(LOG1, FL("After copying length: %d"),
3982 ssid_len);
3983
3984 /* Parse and fetch low RSSI */
3985 if (!tb2[PARAM_BAND]) {
3986 hddLog(LOGE, FL("attr band failed"));
3987 goto fail;
3988 }
3989 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3990 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3991
3992 /* Parse and fetch low RSSI */
3993 if (!tb2[PARAM_RSSI_LOW]) {
3994 hddLog(LOGE, FL("attr low RSSI failed"));
3995 goto fail;
3996 }
3997 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3998 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3999
4000 /* Parse and fetch high RSSI */
4001 if (!tb2[PARAM_RSSI_HIGH]) {
4002 hddLog(LOGE, FL("attr high RSSI failed"));
4003 goto fail;
4004 }
4005 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4006 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4007 i++;
4008 }
4009
4010 context = &hdd_ctx->ext_scan_context;
4011 spin_lock(&hdd_context_lock);
4012 INIT_COMPLETION(context->response_event);
4013 context->request_id = request_id = request->request_id;
4014 spin_unlock(&hdd_context_lock);
4015
4016 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4017 if (!HAL_STATUS_SUCCESS(status)) {
4018 hddLog(LOGE,
4019 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4020 goto fail;
4021 }
4022
4023 vos_mem_free(request);
4024
4025 /* request was sent -- wait for the response */
4026 rc = wait_for_completion_timeout(&context->response_event,
4027 msecs_to_jiffies
4028 (WLAN_WAIT_TIME_EXTSCAN));
4029 if (!rc) {
4030 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4031 retval = -ETIMEDOUT;
4032 } else {
4033 spin_lock(&hdd_context_lock);
4034 if (context->request_id == request_id)
4035 retval = context->response_status;
4036 else
4037 retval = -EINVAL;
4038 spin_unlock(&hdd_context_lock);
4039 }
4040
4041 return retval;
4042
4043fail:
4044 vos_mem_free(request);
4045 return -EINVAL;
4046}
4047
4048/*
4049 * done with short names for the global vendor params
4050 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4051 */
4052#undef PARAM_MAX
4053#undef PARAM_REQUEST_ID
4054#undef PARAMS_NUM_SSID
4055#undef THRESHOLD_PARAM
4056#undef PARAM_SSID
4057#undef PARAM_BAND
4058#undef PARAM_RSSI_LOW
4059#undef PARAM_RSSI_HIGH
4060
4061static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4062 struct wireless_dev *wdev,
4063 const void *data, int dataLen)
4064{
4065 int ret = 0;
4066
4067 vos_ssr_protect(__func__);
4068 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4069 dataLen);
4070 vos_ssr_unprotect(__func__);
4071
4072 return ret;
4073}
4074
4075static int
4076__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4077 struct wireless_dev *wdev,
4078 const void *data,
4079 int data_len)
4080{
4081 tSirEXTScanResetSsidHotlistReqParams request;
4082 struct net_device *dev = wdev->netdev;
4083 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4084 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4085 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4086 struct hdd_ext_scan_context *context;
4087 uint32_t request_id;
4088 eHalStatus status;
4089 int retval;
4090 unsigned long rc;
4091
4092 ENTER();
4093
4094 if (VOS_FTM_MODE == hdd_get_conparam()) {
4095 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4096 return -EINVAL;
4097 }
4098
4099 retval = wlan_hdd_validate_context(hdd_ctx);
4100 if (0 != retval) {
4101 hddLog(LOGE, FL("HDD context is not valid"));
4102 return -EINVAL;
4103 }
4104
4105 /* check the EXTScan Capability */
4106 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4107 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4108 {
4109 hddLog(LOGE,
4110 FL("EXTScan not enabled/supported by Firmware"));
4111 return -EINVAL;
4112 }
4113
4114 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4115 data, data_len,
4116 wlan_hdd_extscan_config_policy)) {
4117 hddLog(LOGE, FL("Invalid ATTR"));
4118 return -EINVAL;
4119 }
4120
4121 /* Parse and fetch request Id */
4122 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4123 hddLog(LOGE, FL("attr request id failed"));
4124 return -EINVAL;
4125 }
4126
4127 request.requestId = nla_get_u32(
4128 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4129 request.sessionId = adapter->sessionId;
4130 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4131 request.sessionId);
4132
4133 context = &hdd_ctx->ext_scan_context;
4134 spin_lock(&hdd_context_lock);
4135 INIT_COMPLETION(context->response_event);
4136 context->request_id = request_id = request.requestId;
4137 spin_unlock(&hdd_context_lock);
4138
4139 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4140 if (!HAL_STATUS_SUCCESS(status)) {
4141 hddLog(LOGE,
4142 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4143 return -EINVAL;
4144 }
4145
4146 /* request was sent -- wait for the response */
4147 rc = wait_for_completion_timeout(&context->response_event,
4148 msecs_to_jiffies
4149 (WLAN_WAIT_TIME_EXTSCAN));
4150 if (!rc) {
4151 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4152 retval = -ETIMEDOUT;
4153 } else {
4154 spin_lock(&hdd_context_lock);
4155 if (context->request_id == request_id)
4156 retval = context->response_status;
4157 else
4158 retval = -EINVAL;
4159 spin_unlock(&hdd_context_lock);
4160 }
4161
4162 return retval;
4163}
4164
4165static int
4166wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4167 struct wireless_dev *wdev,
4168 const void *data,
4169 int data_len)
4170{
4171 int ret;
4172
4173 vos_ssr_protect(__func__);
4174 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4175 data, data_len);
4176 vos_ssr_unprotect(__func__);
4177
4178 return ret;
4179}
4180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304181static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304183 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184{
4185 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4186 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4187 tANI_U8 numChannels = 0;
4188 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304189 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 tWifiBand wifiBand;
4191 eHalStatus status;
4192 struct sk_buff *replySkb;
4193 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304194 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 status = wlan_hdd_validate_context(pHddCtx);
4199 if (0 != status)
4200 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 return -EINVAL;
4202 }
Dino Myclee8843b32014-07-04 14:21:45 +05304203
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4205 data, dataLen,
4206 wlan_hdd_extscan_config_policy)) {
4207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4208 return -EINVAL;
4209 }
4210
4211 /* Parse and fetch request Id */
4212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4214 return -EINVAL;
4215 }
4216 requestId = nla_get_u32(
4217 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4219
4220 /* Parse and fetch wifi band */
4221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4222 {
4223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4224 return -EINVAL;
4225 }
4226 wifiBand = nla_get_u32(
4227 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4229
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304230 /* Parse and fetch max channels */
4231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4232 {
4233 hddLog(LOGE, FL("attr max channels failed"));
4234 return -EINVAL;
4235 }
4236 maxChannels = nla_get_u32(
4237 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4241 wifiBand, ChannelList,
4242 &numChannels);
4243 if (eHAL_STATUS_SUCCESS != status) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR,
4245 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4246 return -EINVAL;
4247 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304248
4249 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304251
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252 for (i = 0; i < numChannels; i++)
4253 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4254
4255 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4256 sizeof(u32) * numChannels +
4257 NLMSG_HDRLEN);
4258
4259 if (!replySkb) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("valid channels: buffer alloc fail"));
4262 return -EINVAL;
4263 }
4264 if (nla_put_u32(replySkb,
4265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4266 numChannels) ||
4267 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4268 sizeof(u32) * numChannels, ChannelList)) {
4269
4270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4271 kfree_skb(replySkb);
4272 return -EINVAL;
4273 }
4274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304275 ret = cfg80211_vendor_cmd_reply(replySkb);
4276
4277 EXIT();
4278 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279}
4280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304281static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4282 struct wireless_dev *wdev,
4283 const void *data, int dataLen)
4284{
4285 int ret = 0;
4286
4287 vos_ssr_protect(__func__);
4288 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4289 dataLen);
4290 vos_ssr_unprotect(__func__);
4291
4292 return ret;
4293}
4294
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304295static int hdd_extscan_start_fill_bucket_channel_spec(
4296 hdd_context_t *pHddCtx,
4297 tpSirEXTScanStartReqParams pReqMsg,
4298 struct nlattr **tb)
4299{
4300 struct nlattr *bucket[
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4302 struct nlattr *channel[
4303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4304 struct nlattr *buckets;
4305 struct nlattr *channels;
4306 int rem1, rem2;
4307 eHalStatus status;
4308 tANI_U8 bktIndex, j, numChannels;
4309 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4310 tANI_U32 passive_max_chn_time, active_max_chn_time;
4311
4312 bktIndex = 0;
4313
4314 nla_for_each_nested(buckets,
4315 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4316 if (nla_parse(bucket,
4317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4318 nla_data(buckets), nla_len(buckets), NULL)) {
4319 hddLog(LOGE, FL("nla_parse failed"));
4320 return -EINVAL;
4321 }
4322
4323 /* Parse and fetch bucket spec */
4324 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4325 hddLog(LOGE, FL("attr bucket index failed"));
4326 return -EINVAL;
4327 }
4328 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4329 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4330 hddLog(LOG1, FL("Bucket spec Index %d"),
4331 pReqMsg->buckets[bktIndex].bucket);
4332
4333 /* Parse and fetch wifi band */
4334 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4335 hddLog(LOGE, FL("attr wifi band failed"));
4336 return -EINVAL;
4337 }
4338 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4339 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4340 hddLog(LOG1, FL("Wifi band %d"),
4341 pReqMsg->buckets[bktIndex].band);
4342
4343 /* Parse and fetch period */
4344 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4345 hddLog(LOGE, FL("attr period failed"));
4346 return -EINVAL;
4347 }
4348 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4349 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4350 hddLog(LOG1, FL("period %d"),
4351 pReqMsg->buckets[bktIndex].period);
4352
4353 /* Parse and fetch report events */
4354 if (!bucket[
4355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4356 hddLog(LOGE, FL("attr report events failed"));
4357 return -EINVAL;
4358 }
4359 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4360 bucket[
4361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4362 hddLog(LOG1, FL("report events %d"),
4363 pReqMsg->buckets[bktIndex].reportEvents);
4364
4365 /* Parse and fetch max period */
4366 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4367 hddLog(LOGE, FL("attr max period failed"));
4368 return -EINVAL;
4369 }
4370 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4371 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4372 hddLog(LOG1, FL("max period %u"),
4373 pReqMsg->buckets[bktIndex].max_period);
4374
4375 /* Parse and fetch exponent */
4376 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4377 hddLog(LOGE, FL("attr exponent failed"));
4378 return -EINVAL;
4379 }
4380 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4381 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4382 hddLog(LOG1, FL("exponent %u"),
4383 pReqMsg->buckets[bktIndex].exponent);
4384
4385 /* Parse and fetch step count */
4386 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4387 hddLog(LOGE, FL("attr step count failed"));
4388 return -EINVAL;
4389 }
4390 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4391 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4392 hddLog(LOG1, FL("Step count %u"),
4393 pReqMsg->buckets[bktIndex].step_count);
4394
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4396 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4397
4398 /* Framework shall pass the channel list if the input WiFi band is
4399 * WIFI_BAND_UNSPECIFIED.
4400 * If the input WiFi band is specified (any value other than
4401 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4402 */
4403 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4404 numChannels = 0;
4405 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4406 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4407 pReqMsg->buckets[bktIndex].band,
4408 chanList, &numChannels);
4409 if (!HAL_STATUS_SUCCESS(status)) {
4410 hddLog(LOGE,
4411 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4412 status);
4413 return -EINVAL;
4414 }
4415
4416 pReqMsg->buckets[bktIndex].numChannels =
4417 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4418 hddLog(LOG1, FL("Num channels %d"),
4419 pReqMsg->buckets[bktIndex].numChannels);
4420
4421 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4422 j++) {
4423 pReqMsg->buckets[bktIndex].channels[j].channel =
4424 chanList[j];
4425 pReqMsg->buckets[bktIndex].channels[j].
4426 chnlClass = 0;
4427 if (CSR_IS_CHANNEL_DFS(
4428 vos_freq_to_chan(chanList[j]))) {
4429 pReqMsg->buckets[bktIndex].channels[j].
4430 passive = 1;
4431 pReqMsg->buckets[bktIndex].channels[j].
4432 dwellTimeMs = passive_max_chn_time;
4433 } else {
4434 pReqMsg->buckets[bktIndex].channels[j].
4435 passive = 0;
4436 pReqMsg->buckets[bktIndex].channels[j].
4437 dwellTimeMs = active_max_chn_time;
4438 }
4439
4440 hddLog(LOG1,
4441 "Channel %u Passive %u Dwell time %u ms",
4442 pReqMsg->buckets[bktIndex].channels[j].channel,
4443 pReqMsg->buckets[bktIndex].channels[j].passive,
4444 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4445 }
4446
4447 bktIndex++;
4448 continue;
4449 }
4450
4451 /* Parse and fetch number of channels */
4452 if (!bucket[
4453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4454 hddLog(LOGE, FL("attr num channels failed"));
4455 return -EINVAL;
4456 }
4457
4458 pReqMsg->buckets[bktIndex].numChannels =
4459 nla_get_u32(bucket[
4460 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4461 hddLog(LOG1, FL("num channels %d"),
4462 pReqMsg->buckets[bktIndex].numChannels);
4463
4464 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4465 hddLog(LOGE, FL("attr channel spec failed"));
4466 return -EINVAL;
4467 }
4468
4469 j = 0;
4470 nla_for_each_nested(channels,
4471 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4472 if (nla_parse(channel,
4473 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4474 nla_data(channels), nla_len(channels),
4475 wlan_hdd_extscan_config_policy)) {
4476 hddLog(LOGE, FL("nla_parse failed"));
4477 return -EINVAL;
4478 }
4479
4480 /* Parse and fetch channel */
4481 if (!channel[
4482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4483 hddLog(LOGE, FL("attr channel failed"));
4484 return -EINVAL;
4485 }
4486 pReqMsg->buckets[bktIndex].channels[j].channel =
4487 nla_get_u32(channel[
4488 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4489 hddLog(LOG1, FL("channel %u"),
4490 pReqMsg->buckets[bktIndex].channels[j].channel);
4491
4492 /* Parse and fetch dwell time */
4493 if (!channel[
4494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4495 hddLog(LOGE, FL("attr dwelltime failed"));
4496 return -EINVAL;
4497 }
4498 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4499 nla_get_u32(channel[
4500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4501
4502 hddLog(LOG1, FL("Dwell time (%u ms)"),
4503 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4504
4505
4506 /* Parse and fetch channel spec passive */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4509 hddLog(LOGE,
4510 FL("attr channel spec passive failed"));
4511 return -EINVAL;
4512 }
4513 pReqMsg->buckets[bktIndex].channels[j].passive =
4514 nla_get_u8(channel[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4516 hddLog(LOG1, FL("Chnl spec passive %u"),
4517 pReqMsg->buckets[bktIndex].channels[j].passive);
4518
4519 j++;
4520 }
4521
4522 bktIndex++;
4523 }
4524
4525 return 0;
4526}
4527
4528
4529/*
4530 * define short names for the global vendor params
4531 * used by wlan_hdd_cfg80211_extscan_start()
4532 */
4533#define PARAM_MAX \
4534QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4535#define PARAM_REQUEST_ID \
4536QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4537#define PARAM_BASE_PERIOD \
4538QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4539#define PARAM_MAX_AP_PER_SCAN \
4540QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4541#define PARAM_RPT_THRHLD_PERCENT \
4542QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4543#define PARAM_RPT_THRHLD_NUM_SCANS \
4544QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4545#define PARAM_NUM_BUCKETS \
4546QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4547
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304548static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304550 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551{
Dino Myclee8843b32014-07-04 14:21:45 +05304552 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304553 struct net_device *dev = wdev->netdev;
4554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4555 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4556 struct nlattr *tb[PARAM_MAX + 1];
4557 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304559 tANI_U32 request_id;
4560 struct hdd_ext_scan_context *context;
4561 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304563 ENTER();
4564
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304565 if (VOS_FTM_MODE == hdd_get_conparam()) {
4566 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4567 return -EINVAL;
4568 }
4569
Dino Mycle6fb96c12014-06-10 11:52:40 +05304570 status = wlan_hdd_validate_context(pHddCtx);
4571 if (0 != status)
4572 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304573 return -EINVAL;
4574 }
Dino Myclee8843b32014-07-04 14:21:45 +05304575 /* check the EXTScan Capability */
4576 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4577 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4578 {
4579 hddLog(VOS_TRACE_LEVEL_ERROR,
4580 FL("EXTScan not enabled/supported by Firmware"));
4581 return -EINVAL;
4582 }
4583
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 data, dataLen,
4586 wlan_hdd_extscan_config_policy)) {
4587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4588 return -EINVAL;
4589 }
4590
4591 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304592 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4594 return -EINVAL;
4595 }
4596
Dino Myclee8843b32014-07-04 14:21:45 +05304597 pReqMsg = (tpSirEXTScanStartReqParams)
4598 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4601 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 }
4603
4604 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304605 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4607
4608 pReqMsg->sessionId = pAdapter->sessionId;
4609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4610
4611 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304612 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4614 goto fail;
4615 }
4616 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304617 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4619 pReqMsg->basePeriod);
4620
4621 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304622 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4624 goto fail;
4625 }
4626 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304627 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4629 pReqMsg->maxAPperScan);
4630
4631 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4634 goto fail;
4635 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 pReqMsg->reportThresholdPercent = nla_get_u8(
4637 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 pReqMsg->reportThresholdPercent);
4640
4641 /* Parse and fetch report threshold num scans */
4642 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4643 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4644 goto fail;
4645 }
4646 pReqMsg->reportThresholdNumScans = nla_get_u8(
4647 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4648 hddLog(LOG1, FL("Report Threshold num scans %d"),
4649 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650
4651 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304652 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4654 goto fail;
4655 }
4656 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4659 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4660 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4661 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4662 }
4663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4664 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4668 goto fail;
4669 }
4670
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4674 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304675
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304676 context = &pHddCtx->ext_scan_context;
4677 spin_lock(&hdd_context_lock);
4678 INIT_COMPLETION(context->response_event);
4679 context->request_id = request_id = pReqMsg->requestId;
4680 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304681
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4683 if (!HAL_STATUS_SUCCESS(status)) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 goto fail;
4687 }
4688
4689 /* request was sent -- wait for the response */
4690 rc = wait_for_completion_timeout(&context->response_event,
4691 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4692
4693 if (!rc) {
4694 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4695 retval = -ETIMEDOUT;
4696 } else {
4697 spin_lock(&hdd_context_lock);
4698 if (context->request_id == request_id)
4699 retval = context->response_status;
4700 else
4701 retval = -EINVAL;
4702 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 }
4704
Dino Myclee8843b32014-07-04 14:21:45 +05304705 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304706 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
4709fail:
4710 vos_mem_free(pReqMsg);
4711 return -EINVAL;
4712}
4713
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714/*
4715 * done with short names for the global vendor params
4716 * used by wlan_hdd_cfg80211_extscan_start()
4717 */
4718#undef PARAM_MAX
4719#undef PARAM_REQUEST_ID
4720#undef PARAM_BASE_PERIOD
4721#undef PARAMS_MAX_AP_PER_SCAN
4722#undef PARAMS_RPT_THRHLD_PERCENT
4723#undef PARAMS_RPT_THRHLD_NUM_SCANS
4724#undef PARAMS_NUM_BUCKETS
4725
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304726static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4727 struct wireless_dev *wdev,
4728 const void *data, int dataLen)
4729{
4730 int ret = 0;
4731
4732 vos_ssr_protect(__func__);
4733 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4734 vos_ssr_unprotect(__func__);
4735
4736 return ret;
4737}
4738
4739static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304741 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742{
Dino Myclee8843b32014-07-04 14:21:45 +05304743 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 struct net_device *dev = wdev->netdev;
4745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4748 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304749 int retval;
4750 unsigned long rc;
4751 struct hdd_ext_scan_context *context;
4752 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304754 ENTER();
4755
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304756 if (VOS_FTM_MODE == hdd_get_conparam()) {
4757 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4758 return -EINVAL;
4759 }
4760
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 status = wlan_hdd_validate_context(pHddCtx);
4762 if (0 != status)
4763 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 return -EINVAL;
4765 }
Dino Myclee8843b32014-07-04 14:21:45 +05304766 /* check the EXTScan Capability */
4767 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4768 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR,
4771 FL("EXTScan not enabled/supported by Firmware"));
4772 return -EINVAL;
4773 }
4774
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4776 data, dataLen,
4777 wlan_hdd_extscan_config_policy)) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4779 return -EINVAL;
4780 }
4781
4782 /* Parse and fetch request Id */
4783 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4785 return -EINVAL;
4786 }
4787
Dino Myclee8843b32014-07-04 14:21:45 +05304788 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Dino Myclee8843b32014-07-04 14:21:45 +05304792 reqMsg.sessionId = pAdapter->sessionId;
4793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304795 context = &pHddCtx->ext_scan_context;
4796 spin_lock(&hdd_context_lock);
4797 INIT_COMPLETION(context->response_event);
4798 context->request_id = request_id = reqMsg.sessionId;
4799 spin_unlock(&hdd_context_lock);
4800
Dino Myclee8843b32014-07-04 14:21:45 +05304801 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (!HAL_STATUS_SUCCESS(status)) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR,
4804 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 return -EINVAL;
4806 }
4807
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304808 /* request was sent -- wait for the response */
4809 rc = wait_for_completion_timeout(&context->response_event,
4810 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4811
4812 if (!rc) {
4813 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4814 retval = -ETIMEDOUT;
4815 } else {
4816 spin_lock(&hdd_context_lock);
4817 if (context->request_id == request_id)
4818 retval = context->response_status;
4819 else
4820 retval = -EINVAL;
4821 spin_unlock(&hdd_context_lock);
4822 }
4823
4824 return retval;
4825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304826 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 return 0;
4828}
4829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304830static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4831 struct wireless_dev *wdev,
4832 const void *data, int dataLen)
4833{
4834 int ret = 0;
4835
4836 vos_ssr_protect(__func__);
4837 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4838 vos_ssr_unprotect(__func__);
4839
4840 return ret;
4841}
4842
4843static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304845 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846{
Dino Myclee8843b32014-07-04 14:21:45 +05304847 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 struct net_device *dev = wdev->netdev;
4849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4851 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4852 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304853 struct hdd_ext_scan_context *context;
4854 tANI_U32 request_id;
4855 unsigned long rc;
4856 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304858 ENTER();
4859
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304860 if (VOS_FTM_MODE == hdd_get_conparam()) {
4861 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4862 return -EINVAL;
4863 }
4864
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865 status = wlan_hdd_validate_context(pHddCtx);
4866 if (0 != status)
4867 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304868 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304869 return -EINVAL;
4870 }
Dino Myclee8843b32014-07-04 14:21:45 +05304871 /* check the EXTScan Capability */
4872 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4873 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4874 {
4875 hddLog(VOS_TRACE_LEVEL_ERROR,
4876 FL("EXTScan not enabled/supported by Firmware"));
4877 return -EINVAL;
4878 }
4879
Dino Mycle6fb96c12014-06-10 11:52:40 +05304880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4881 data, dataLen,
4882 wlan_hdd_extscan_config_policy)) {
4883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4884 return -EINVAL;
4885 }
4886
4887 /* Parse and fetch request Id */
4888 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4890 return -EINVAL;
4891 }
4892
Dino Myclee8843b32014-07-04 14:21:45 +05304893 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Dino Myclee8843b32014-07-04 14:21:45 +05304897 reqMsg.sessionId = pAdapter->sessionId;
4898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304900 context = &pHddCtx->ext_scan_context;
4901 spin_lock(&hdd_context_lock);
4902 INIT_COMPLETION(context->response_event);
4903 context->request_id = request_id = reqMsg.requestId;
4904 spin_unlock(&hdd_context_lock);
4905
Dino Myclee8843b32014-07-04 14:21:45 +05304906 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 if (!HAL_STATUS_SUCCESS(status)) {
4908 hddLog(VOS_TRACE_LEVEL_ERROR,
4909 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304910 return -EINVAL;
4911 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912
4913 /* request was sent -- wait for the response */
4914 rc = wait_for_completion_timeout(&context->response_event,
4915 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4916 if (!rc) {
4917 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4918 retval = -ETIMEDOUT;
4919 } else {
4920 spin_lock(&hdd_context_lock);
4921 if (context->request_id == request_id)
4922 retval = context->response_status;
4923 else
4924 retval = -EINVAL;
4925 spin_unlock(&hdd_context_lock);
4926 }
4927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304928 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930}
4931
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304932static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4933 struct wireless_dev *wdev,
4934 const void *data, int dataLen)
4935{
4936 int ret = 0;
4937
4938 vos_ssr_protect(__func__);
4939 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4940 vos_ssr_unprotect(__func__);
4941
4942 return ret;
4943}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304944#endif /* WLAN_FEATURE_EXTSCAN */
4945
Atul Mittal115287b2014-07-08 13:26:33 +05304946/*EXT TDLS*/
4947static const struct nla_policy
4948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4949{
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4953 {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4956
4957};
4958
4959static const struct nla_policy
4960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4961{
4962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4963
4964};
4965
4966static const struct nla_policy
4967wlan_hdd_tdls_config_state_change_policy[
4968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4969{
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304976
4977};
4978
4979static const struct nla_policy
4980wlan_hdd_tdls_config_get_status_policy[
4981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4982{
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304989
4990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304991
4992static const struct nla_policy
4993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4994{
4995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4996};
4997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304998static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304999 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305000 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305001 int data_len)
5002{
5003
5004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305007 ENTER();
5008
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305010 return -EINVAL;
5011 }
5012 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305013 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305014 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305015 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305016 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305017 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305018 return -ENOTSUPP;
5019 }
5020
5021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5022 data, data_len, wlan_hdd_mac_config)) {
5023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5024 return -EINVAL;
5025 }
5026
5027 /* Parse and fetch mac address */
5028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5030 return -EINVAL;
5031 }
5032
5033 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5034 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5035 VOS_MAC_ADDR_LAST_3_BYTES);
5036
Siddharth Bhal76972212014-10-15 16:22:51 +05305037 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5038
5039 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5041 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305042 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5044 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5045 {
5046 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5047 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5048 VOS_MAC_ADDRESS_LEN);
5049 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
Siddharth Bhal76972212014-10-15 16:22:51 +05305052 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5053 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305054 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5055 }
5056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305057 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 return 0;
5059}
5060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305061static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5062 struct wireless_dev *wdev,
5063 const void *data,
5064 int data_len)
5065{
5066 int ret = 0;
5067
5068 vos_ssr_protect(__func__);
5069 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5070 vos_ssr_unprotect(__func__);
5071
5072 return ret;
5073}
5074
5075static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305076 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305078 int data_len)
5079{
5080 u8 peer[6] = {0};
5081 struct net_device *dev = wdev->netdev;
5082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5085 eHalStatus ret;
5086 tANI_S32 state;
5087 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305088 tANI_S32 global_operating_class = 0;
5089 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305090 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305091 int retVal;
5092
5093 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305094
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305095 if (!pAdapter) {
5096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5097 return -EINVAL;
5098 }
5099
Atul Mittal115287b2014-07-08 13:26:33 +05305100 ret = wlan_hdd_validate_context(pHddCtx);
5101 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305103 return -EINVAL;
5104 }
5105 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305107 return -ENOTSUPP;
5108 }
5109 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5110 data, data_len,
5111 wlan_hdd_tdls_config_get_status_policy)) {
5112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5113 return -EINVAL;
5114 }
5115
5116 /* Parse and fetch mac address */
5117 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5119 return -EINVAL;
5120 }
5121
5122 memcpy(peer, nla_data(
5123 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5124 sizeof(peer));
5125 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5126
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305127 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305130 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305131 NLMSG_HDRLEN);
5132
5133 if (!skb) {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
5135 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5136 return -EINVAL;
5137 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305139 reason,
5140 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305141 global_operating_class,
5142 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305143 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305144 if (nla_put_s32(skb,
5145 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5146 state) ||
5147 nla_put_s32(skb,
5148 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5149 reason) ||
5150 nla_put_s32(skb,
5151 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5152 global_operating_class) ||
5153 nla_put_s32(skb,
5154 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5155 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305156
5157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5158 goto nla_put_failure;
5159 }
5160
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305161 retVal = cfg80211_vendor_cmd_reply(skb);
5162 EXIT();
5163 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305164
5165nla_put_failure:
5166 kfree_skb(skb);
5167 return -EINVAL;
5168}
5169
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305170static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5171 struct wireless_dev *wdev,
5172 const void *data,
5173 int data_len)
5174{
5175 int ret = 0;
5176
5177 vos_ssr_protect(__func__);
5178 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5179 vos_ssr_unprotect(__func__);
5180
5181 return ret;
5182}
5183
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305184static int wlan_hdd_cfg80211_exttdls_callback(
5185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5186 const tANI_U8* mac,
5187#else
5188 tANI_U8* mac,
5189#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305190 tANI_S32 state,
5191 tANI_S32 reason,
5192 void *ctx)
5193{
5194 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305195 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 tANI_S32 global_operating_class = 0;
5197 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305198 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305200 ENTER();
5201
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305202 if (!pAdapter) {
5203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5204 return -EINVAL;
5205 }
5206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305208 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305210 return -EINVAL;
5211 }
5212
5213 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305215 return -ENOTSUPP;
5216 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305217 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5219 NULL,
5220#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305221 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5222 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5223 GFP_KERNEL);
5224
5225 if (!skb) {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
5227 FL("cfg80211_vendor_event_alloc failed"));
5228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305231 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5232 reason,
5233 state,
5234 global_operating_class,
5235 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305236 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5237 MAC_ADDR_ARRAY(mac));
5238
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305239 if (nla_put(skb,
5240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5241 VOS_MAC_ADDR_SIZE, mac) ||
5242 nla_put_s32(skb,
5243 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5244 state) ||
5245 nla_put_s32(skb,
5246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5247 reason) ||
5248 nla_put_s32(skb,
5249 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5250 channel) ||
5251 nla_put_s32(skb,
5252 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5253 global_operating_class)
5254 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5256 goto nla_put_failure;
5257 }
5258
5259 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305260 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305261 return (0);
5262
5263nla_put_failure:
5264 kfree_skb(skb);
5265 return -EINVAL;
5266}
5267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305268static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305269 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305270 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305271 int data_len)
5272{
5273 u8 peer[6] = {0};
5274 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305275 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5276 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5277 eHalStatus status;
5278 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305279 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305280 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281
5282 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305283
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305284 if (!dev) {
5285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5286 return -EINVAL;
5287 }
5288
5289 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5290 if (!pAdapter) {
5291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5292 return -EINVAL;
5293 }
5294
Atul Mittal115287b2014-07-08 13:26:33 +05305295 status = wlan_hdd_validate_context(pHddCtx);
5296 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305298 return -EINVAL;
5299 }
5300 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305302 return -ENOTSUPP;
5303 }
5304 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5305 data, data_len,
5306 wlan_hdd_tdls_config_enable_policy)) {
5307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5308 return -EINVAL;
5309 }
5310
5311 /* Parse and fetch mac address */
5312 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5314 return -EINVAL;
5315 }
5316
5317 memcpy(peer, nla_data(
5318 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5319 sizeof(peer));
5320 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5321
5322 /* Parse and fetch channel */
5323 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5325 return -EINVAL;
5326 }
5327 pReqMsg.channel = nla_get_s32(
5328 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5330
5331 /* Parse and fetch global operating class */
5332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5334 return -EINVAL;
5335 }
5336 pReqMsg.global_operating_class = nla_get_s32(
5337 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5339 pReqMsg.global_operating_class);
5340
5341 /* Parse and fetch latency ms */
5342 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5344 return -EINVAL;
5345 }
5346 pReqMsg.max_latency_ms = nla_get_s32(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5349 pReqMsg.max_latency_ms);
5350
5351 /* Parse and fetch required bandwidth kbps */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5354 return -EINVAL;
5355 }
5356
5357 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5358 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5360 pReqMsg.min_bandwidth_kbps);
5361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305362 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305363 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305364 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305365 wlan_hdd_cfg80211_exttdls_callback);
5366
5367 EXIT();
5368 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305369}
5370
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305371static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5372 struct wireless_dev *wdev,
5373 const void *data,
5374 int data_len)
5375{
5376 int ret = 0;
5377
5378 vos_ssr_protect(__func__);
5379 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5380 vos_ssr_unprotect(__func__);
5381
5382 return ret;
5383}
5384
5385static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305386 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305387 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305388 int data_len)
5389{
5390 u8 peer[6] = {0};
5391 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5393 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5394 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305396 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305397
5398 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305399
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305400 if (!dev) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5402 return -EINVAL;
5403 }
5404
5405 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406 if (!pAdapter) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5408 return -EINVAL;
5409 }
5410
Atul Mittal115287b2014-07-08 13:26:33 +05305411 status = wlan_hdd_validate_context(pHddCtx);
5412 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305414 return -EINVAL;
5415 }
5416 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305418 return -ENOTSUPP;
5419 }
5420 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5421 data, data_len,
5422 wlan_hdd_tdls_config_disable_policy)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5424 return -EINVAL;
5425 }
5426 /* Parse and fetch mac address */
5427 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5429 return -EINVAL;
5430 }
5431
5432 memcpy(peer, nla_data(
5433 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5434 sizeof(peer));
5435 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305437 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5438
5439 EXIT();
5440 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305441}
5442
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305443static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5444 struct wireless_dev *wdev,
5445 const void *data,
5446 int data_len)
5447{
5448 int ret = 0;
5449
5450 vos_ssr_protect(__func__);
5451 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5452 vos_ssr_unprotect(__func__);
5453
5454 return ret;
5455}
5456
Dasari Srinivas7875a302014-09-26 17:50:57 +05305457static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305458__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305459 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305460 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305461{
5462 struct net_device *dev = wdev->netdev;
5463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5465 struct sk_buff *skb = NULL;
5466 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305467 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305469 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305470
5471 ret = wlan_hdd_validate_context(pHddCtx);
5472 if (0 != ret)
5473 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305474 return ret;
5475 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305476 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5477 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5478 fset |= WIFI_FEATURE_INFRA;
5479 }
5480
5481 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5482 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5483 fset |= WIFI_FEATURE_INFRA_5G;
5484 }
5485
5486#ifdef WLAN_FEATURE_P2P
5487 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5488 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5489 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5490 fset |= WIFI_FEATURE_P2P;
5491 }
5492#endif
5493
5494 /* Soft-AP is supported currently by default */
5495 fset |= WIFI_FEATURE_SOFT_AP;
5496
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305497 /* HOTSPOT is a supplicant feature, enable it by default */
5498 fset |= WIFI_FEATURE_HOTSPOT;
5499
Dasari Srinivas7875a302014-09-26 17:50:57 +05305500#ifdef WLAN_FEATURE_EXTSCAN
5501 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5502 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5503 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5504 fset |= WIFI_FEATURE_EXTSCAN;
5505 }
5506#endif
5507
Dasari Srinivas7875a302014-09-26 17:50:57 +05305508 if (sme_IsFeatureSupportedByFW(NAN)) {
5509 hddLog(LOG1, FL("NAN is supported by firmware"));
5510 fset |= WIFI_FEATURE_NAN;
5511 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512
5513 /* D2D RTT is not supported currently by default */
5514 if (sme_IsFeatureSupportedByFW(RTT)) {
5515 hddLog(LOG1, FL("RTT is supported by firmware"));
5516 fset |= WIFI_FEATURE_D2AP_RTT;
5517 }
5518
5519#ifdef FEATURE_WLAN_BATCH_SCAN
5520 if (fset & WIFI_FEATURE_EXTSCAN) {
5521 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5522 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5523 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5524 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5525 fset |= WIFI_FEATURE_BATCH_SCAN;
5526 }
5527#endif
5528
5529#ifdef FEATURE_WLAN_SCAN_PNO
5530 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5531 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5532 hddLog(LOG1, FL("PNO is supported by firmware"));
5533 fset |= WIFI_FEATURE_PNO;
5534 }
5535#endif
5536
5537 /* STA+STA is supported currently by default */
5538 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5539
5540#ifdef FEATURE_WLAN_TDLS
5541 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5542 sme_IsFeatureSupportedByFW(TDLS)) {
5543 hddLog(LOG1, FL("TDLS is supported by firmware"));
5544 fset |= WIFI_FEATURE_TDLS;
5545 }
5546
5547 /* TDLS_OFFCHANNEL is not supported currently by default */
5548#endif
5549
5550#ifdef WLAN_AP_STA_CONCURRENCY
5551 /* AP+STA concurrency is supported currently by default */
5552 fset |= WIFI_FEATURE_AP_STA;
5553#endif
5554
Mukul Sharma5add0532015-08-17 15:57:47 +05305555#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5556 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5557 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5558#endif
5559
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5561 NLMSG_HDRLEN);
5562
5563 if (!skb) {
5564 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5565 return -EINVAL;
5566 }
5567 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5568
5569 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5570 hddLog(LOGE, FL("nla put fail"));
5571 goto nla_put_failure;
5572 }
5573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305574 ret = cfg80211_vendor_cmd_reply(skb);
5575 EXIT();
5576 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577
5578nla_put_failure:
5579 kfree_skb(skb);
5580 return -EINVAL;
5581}
5582
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305583static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data, int data_len)
5587{
5588 int ret = 0;
5589
5590 vos_ssr_protect(__func__);
5591 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5592 vos_ssr_unprotect(__func__);
5593
5594 return ret;
5595}
5596
5597static int
5598__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305600 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305601{
5602 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5603 uint8_t i, feature_sets, max_feature_sets;
5604 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5605 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5607 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305608
5609 ENTER();
5610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611 ret = wlan_hdd_validate_context(pHddCtx);
5612 if (0 != ret)
5613 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305614 return ret;
5615 }
5616
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305617 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5618 data, data_len, NULL)) {
5619 hddLog(LOGE, FL("Invalid ATTR"));
5620 return -EINVAL;
5621 }
5622
5623 /* Parse and fetch max feature set */
5624 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5625 hddLog(LOGE, FL("Attr max feature set size failed"));
5626 return -EINVAL;
5627 }
5628 max_feature_sets = nla_get_u32(
5629 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5630 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5631
5632 /* Fill feature combination matrix */
5633 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305634 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5635 WIFI_FEATURE_P2P;
5636
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305637 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5638 WIFI_FEATURE_SOFT_AP;
5639
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305640 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5641 WIFI_FEATURE_SOFT_AP;
5642
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305643 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5644 WIFI_FEATURE_SOFT_AP |
5645 WIFI_FEATURE_P2P;
5646
5647 /* Add more feature combinations here */
5648
5649 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5650 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5651 hddLog(LOG1, "Feature set matrix");
5652 for (i = 0; i < feature_sets; i++)
5653 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5654
5655 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5656 sizeof(u32) * feature_sets +
5657 NLMSG_HDRLEN);
5658
5659 if (reply_skb) {
5660 if (nla_put_u32(reply_skb,
5661 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5662 feature_sets) ||
5663 nla_put(reply_skb,
5664 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5665 sizeof(u32) * feature_sets, feature_set_matrix)) {
5666 hddLog(LOGE, FL("nla put fail"));
5667 kfree_skb(reply_skb);
5668 return -EINVAL;
5669 }
5670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305671 ret = cfg80211_vendor_cmd_reply(reply_skb);
5672 EXIT();
5673 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305674 }
5675 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5676 return -ENOMEM;
5677
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305678}
5679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305680static int
5681wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5682 struct wireless_dev *wdev,
5683 const void *data, int data_len)
5684{
5685 int ret = 0;
5686
5687 vos_ssr_protect(__func__);
5688 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5689 data_len);
5690 vos_ssr_unprotect(__func__);
5691
5692 return ret;
5693}
5694
c_manjeecfd1efb2015-09-25 19:32:34 +05305695
5696static int
5697__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5698 struct wireless_dev *wdev,
5699 const void *data, int data_len)
5700{
5701 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5702 int ret;
5703 ENTER();
5704
5705 ret = wlan_hdd_validate_context(pHddCtx);
5706 if (0 != ret)
5707 {
5708 return ret;
5709 }
5710
5711 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5712 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5713 {
5714 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5715 return -EINVAL;
5716 }
5717 /*call common API for FW mem dump req*/
5718 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5719
5720 EXIT();
5721 return ret;
5722}
5723
5724/**
5725 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5726 * @wiphy: pointer to wireless wiphy structure.
5727 * @wdev: pointer to wireless_dev structure.
5728 * @data: Pointer to the NL data.
5729 * @data_len:Length of @data
5730 *
5731 * This is called when wlan driver needs to get the firmware memory dump
5732 * via vendor specific command.
5733 *
5734 * Return: 0 on success, error number otherwise.
5735 */
5736
5737static int
5738wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5739 struct wireless_dev *wdev,
5740 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305741{
5742 int ret = 0;
5743 vos_ssr_protect(__func__);
5744 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5745 data_len);
5746 vos_ssr_unprotect(__func__);
5747 return ret;
5748}
c_manjeecfd1efb2015-09-25 19:32:34 +05305749
Sushant Kaushik8e644982015-09-23 12:18:54 +05305750static const struct
5751nla_policy
5752qca_wlan_vendor_wifi_logger_start_policy
5753[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5754 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5755 = {.type = NLA_U32 },
5756 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5757 = {.type = NLA_U32 },
5758 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5759 = {.type = NLA_U32 },
5760};
5761
5762/**
5763 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5764 * or disable the collection of packet statistics from the firmware
5765 * @wiphy: WIPHY structure pointer
5766 * @wdev: Wireless device structure pointer
5767 * @data: Pointer to the data received
5768 * @data_len: Length of the data received
5769 *
5770 * This function is used to enable or disable the collection of packet
5771 * statistics from the firmware
5772 *
5773 * Return: 0 on success and errno on failure
5774 */
5775static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5776 struct wireless_dev *wdev,
5777 const void *data,
5778 int data_len)
5779{
5780 eHalStatus status;
5781 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5782 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5783 tAniWifiStartLog start_log;
5784
5785 status = wlan_hdd_validate_context(hdd_ctx);
5786 if (0 != status) {
5787 return -EINVAL;
5788 }
5789
5790 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5791 data, data_len,
5792 qca_wlan_vendor_wifi_logger_start_policy)) {
5793 hddLog(LOGE, FL("Invalid attribute"));
5794 return -EINVAL;
5795 }
5796
5797 /* Parse and fetch ring id */
5798 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5799 hddLog(LOGE, FL("attr ATTR failed"));
5800 return -EINVAL;
5801 }
5802 start_log.ringId = nla_get_u32(
5803 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5804 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5805
5806 /* Parse and fetch verbose level */
5807 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5808 hddLog(LOGE, FL("attr verbose_level failed"));
5809 return -EINVAL;
5810 }
5811 start_log.verboseLevel = nla_get_u32(
5812 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5813 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5814
5815 /* Parse and fetch flag */
5816 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5817 hddLog(LOGE, FL("attr flag failed"));
5818 return -EINVAL;
5819 }
5820 start_log.flag = nla_get_u32(
5821 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5822 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5823
5824 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
5825 !hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable)
5826 {
5827 hddLog(LOGE, FL("per pkt stats not enabled"));
5828 return -EINVAL;
5829 }
5830 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
5831
5832 return 0;
5833}
5834
5835/**
5836 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5837 * or disable the collection of packet statistics from the firmware
5838 * @wiphy: WIPHY structure pointer
5839 * @wdev: Wireless device structure pointer
5840 * @data: Pointer to the data received
5841 * @data_len: Length of the data received
5842 *
5843 * This function is used to enable or disable the collection of packet
5844 * statistics from the firmware
5845 *
5846 * Return: 0 on success and errno on failure
5847 */
5848static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5849 struct wireless_dev *wdev,
5850 const void *data,
5851 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305852{
5853 int ret = 0;
5854
5855 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305856
5857 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5858 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305859 vos_ssr_unprotect(__func__);
5860
5861 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305862}
5863
5864
Agarwal Ashish738843c2014-09-25 12:27:56 +05305865static const struct nla_policy
5866wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5867 +1] =
5868{
5869 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5870};
5871
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305872static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305873 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305874 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305875 int data_len)
5876{
5877 struct net_device *dev = wdev->netdev;
5878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5879 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5880 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5881 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5882 eHalStatus status;
5883 u32 dfsFlag = 0;
5884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305885 ENTER();
5886
Agarwal Ashish738843c2014-09-25 12:27:56 +05305887 status = wlan_hdd_validate_context(pHddCtx);
5888 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305889 return -EINVAL;
5890 }
5891 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5892 data, data_len,
5893 wlan_hdd_set_no_dfs_flag_config_policy)) {
5894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5895 return -EINVAL;
5896 }
5897
5898 /* Parse and fetch required bandwidth kbps */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5901 return -EINVAL;
5902 }
5903
5904 dfsFlag = nla_get_u32(
5905 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5906 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5907 dfsFlag);
5908
5909 pHddCtx->disable_dfs_flag = dfsFlag;
5910
5911 sme_disable_dfs_channel(hHal, dfsFlag);
5912 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305913
5914 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305915 return 0;
5916}
Atul Mittal115287b2014-07-08 13:26:33 +05305917
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305918static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5919 struct wireless_dev *wdev,
5920 const void *data,
5921 int data_len)
5922{
5923 int ret = 0;
5924
5925 vos_ssr_protect(__func__);
5926 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5927 vos_ssr_unprotect(__func__);
5928
5929 return ret;
5930
5931}
5932
Mukul Sharma2a271632014-10-13 14:59:01 +05305933const struct
5934nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5935{
5936 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5937 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5938};
5939
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305940static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305941 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305942{
5943
5944 u8 bssid[6] = {0};
5945 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5946 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5947 eHalStatus status = eHAL_STATUS_SUCCESS;
5948 v_U32_t isFwrRoamEnabled = FALSE;
5949 int ret;
5950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305951 ENTER();
5952
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305953 ret = wlan_hdd_validate_context(pHddCtx);
5954 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305955 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305956 }
5957
5958 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5959 data, data_len,
5960 qca_wlan_vendor_attr);
5961 if (ret){
5962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5963 return -EINVAL;
5964 }
5965
5966 /* Parse and fetch Enable flag */
5967 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5968 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5969 return -EINVAL;
5970 }
5971
5972 isFwrRoamEnabled = nla_get_u32(
5973 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5974
5975 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5976
5977 /* Parse and fetch bssid */
5978 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5980 return -EINVAL;
5981 }
5982
5983 memcpy(bssid, nla_data(
5984 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5985 sizeof(bssid));
5986 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5987
5988 //Update roaming
5989 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305990 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305991 return status;
5992}
5993
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305994static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5995 struct wireless_dev *wdev, const void *data, int data_len)
5996{
5997 int ret = 0;
5998
5999 vos_ssr_protect(__func__);
6000 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6001 vos_ssr_unprotect(__func__);
6002
6003 return ret;
6004}
6005
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306006/**
6007 * __wlan_hdd_cfg80211_setband() - set band
6008 * @wiphy: Pointer to wireless phy
6009 * @wdev: Pointer to wireless device
6010 * @data: Pointer to data
6011 * @data_len: Data length
6012 *
6013 * Return: 0 on success, negative errno on failure
6014 */
6015static int
6016__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6017 struct wireless_dev *wdev,
6018 const void *data,
6019 int data_len)
6020{
6021 struct net_device *dev = wdev->netdev;
6022 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6023 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6024 int ret;
6025 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6026 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6027
6028 ENTER();
6029
6030 ret = wlan_hdd_validate_context(hdd_ctx);
6031 if (0 != ret) {
6032 hddLog(LOGE, FL("HDD context is not valid"));
6033 return ret;
6034 }
6035
6036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6037 policy)) {
6038 hddLog(LOGE, FL("Invalid ATTR"));
6039 return -EINVAL;
6040 }
6041
6042 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6043 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6044 return -EINVAL;
6045 }
6046
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306047 hdd_ctx->isSetBandByNL = TRUE;
6048 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306049 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306050 hdd_ctx->isSetBandByNL = FALSE;
6051
6052 EXIT();
6053 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306054}
6055
6056/**
6057 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6058 * @wiphy: wiphy structure pointer
6059 * @wdev: Wireless device structure pointer
6060 * @data: Pointer to the data received
6061 * @data_len: Length of @data
6062 *
6063 * Return: 0 on success; errno on failure
6064 */
6065static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6066 struct wireless_dev *wdev,
6067 const void *data,
6068 int data_len)
6069{
6070 int ret = 0;
6071
6072 vos_ssr_protect(__func__);
6073 ret = __wlan_hdd_cfg80211_setband(wiphy,
6074 wdev, data, data_len);
6075 vos_ssr_unprotect(__func__);
6076
6077 return ret;
6078}
6079
Sunil Duttc69bccb2014-05-26 21:30:20 +05306080const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6081{
Mukul Sharma2a271632014-10-13 14:59:01 +05306082 {
6083 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6084 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6085 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6086 WIPHY_VENDOR_CMD_NEED_NETDEV |
6087 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306088 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306089 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306090
6091 {
6092 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6093 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6094 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6095 WIPHY_VENDOR_CMD_NEED_NETDEV |
6096 WIPHY_VENDOR_CMD_NEED_RUNNING,
6097 .doit = wlan_hdd_cfg80211_nan_request
6098 },
6099
Sunil Duttc69bccb2014-05-26 21:30:20 +05306100#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6101 {
6102 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6103 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6104 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6105 WIPHY_VENDOR_CMD_NEED_NETDEV |
6106 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306107 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306108 },
6109
6110 {
6111 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6112 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6113 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6114 WIPHY_VENDOR_CMD_NEED_NETDEV |
6115 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306116 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306117 },
6118
6119 {
6120 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6121 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6122 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6123 WIPHY_VENDOR_CMD_NEED_NETDEV |
6124 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306125 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306126 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306127#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306128#ifdef WLAN_FEATURE_EXTSCAN
6129 {
6130 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6131 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6132 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6133 WIPHY_VENDOR_CMD_NEED_NETDEV |
6134 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306135 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306136 },
6137 {
6138 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6139 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6140 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6141 WIPHY_VENDOR_CMD_NEED_NETDEV |
6142 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306143 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306144 },
6145 {
6146 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6147 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6148 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6149 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306150 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306151 },
6152 {
6153 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6154 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6155 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6156 WIPHY_VENDOR_CMD_NEED_NETDEV |
6157 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306158 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306159 },
6160 {
6161 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6162 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6163 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6164 WIPHY_VENDOR_CMD_NEED_NETDEV |
6165 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306166 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306167 },
6168 {
6169 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6170 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6171 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6172 WIPHY_VENDOR_CMD_NEED_NETDEV |
6173 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306174 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306175 },
6176 {
6177 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6178 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6179 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6180 WIPHY_VENDOR_CMD_NEED_NETDEV |
6181 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306182 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306183 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306184 {
6185 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6186 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6187 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6188 WIPHY_VENDOR_CMD_NEED_NETDEV |
6189 WIPHY_VENDOR_CMD_NEED_RUNNING,
6190 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6191 },
6192 {
6193 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6194 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6195 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6196 WIPHY_VENDOR_CMD_NEED_NETDEV |
6197 WIPHY_VENDOR_CMD_NEED_RUNNING,
6198 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6199 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306200#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306201/*EXT TDLS*/
6202 {
6203 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6204 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6205 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6206 WIPHY_VENDOR_CMD_NEED_NETDEV |
6207 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306208 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306209 },
6210 {
6211 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6212 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6213 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6214 WIPHY_VENDOR_CMD_NEED_NETDEV |
6215 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306216 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306217 },
6218 {
6219 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6220 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6221 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6222 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306223 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306224 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306225 {
6226 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6227 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6228 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6229 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306230 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306231 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306232 {
6233 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6234 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6235 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6236 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306237 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306238 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306239 {
6240 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6241 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6242 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6243 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306244 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306245 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306246 {
6247 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6248 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6249 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6250 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306251 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306252 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306253 {
6254 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306255 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6256 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6257 WIPHY_VENDOR_CMD_NEED_NETDEV |
6258 WIPHY_VENDOR_CMD_NEED_RUNNING,
6259 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6260 },
6261 {
6262 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306263 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6264 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6265 WIPHY_VENDOR_CMD_NEED_NETDEV |
6266 WIPHY_VENDOR_CMD_NEED_RUNNING,
6267 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05306268 },
6269 {
6270 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6271 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
6272 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6273 WIPHY_VENDOR_CMD_NEED_NETDEV,
6274 .doit = wlan_hdd_cfg80211_wifi_logger_start
6275 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306276};
6277
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006278/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306279static const
6280struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006281{
6282#ifdef FEATURE_WLAN_CH_AVOID
6283 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306284 .vendor_id = QCA_NL80211_VENDOR_ID,
6285 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006286 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306287#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6288#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6289 {
6290 /* Index = 1*/
6291 .vendor_id = QCA_NL80211_VENDOR_ID,
6292 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6293 },
6294 {
6295 /* Index = 2*/
6296 .vendor_id = QCA_NL80211_VENDOR_ID,
6297 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6298 },
6299 {
6300 /* Index = 3*/
6301 .vendor_id = QCA_NL80211_VENDOR_ID,
6302 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6303 },
6304 {
6305 /* Index = 4*/
6306 .vendor_id = QCA_NL80211_VENDOR_ID,
6307 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6308 },
6309 {
6310 /* Index = 5*/
6311 .vendor_id = QCA_NL80211_VENDOR_ID,
6312 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6313 },
6314 {
6315 /* Index = 6*/
6316 .vendor_id = QCA_NL80211_VENDOR_ID,
6317 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6318 },
6319#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306320#ifdef WLAN_FEATURE_EXTSCAN
6321 {
6322 .vendor_id = QCA_NL80211_VENDOR_ID,
6323 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6324 },
6325 {
6326 .vendor_id = QCA_NL80211_VENDOR_ID,
6327 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6328 },
6329 {
6330 .vendor_id = QCA_NL80211_VENDOR_ID,
6331 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6332 },
6333 {
6334 .vendor_id = QCA_NL80211_VENDOR_ID,
6335 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6336 },
6337 {
6338 .vendor_id = QCA_NL80211_VENDOR_ID,
6339 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6340 },
6341 {
6342 .vendor_id = QCA_NL80211_VENDOR_ID,
6343 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6344 },
6345 {
6346 .vendor_id = QCA_NL80211_VENDOR_ID,
6347 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6348 },
6349 {
6350 .vendor_id = QCA_NL80211_VENDOR_ID,
6351 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6352 },
6353 {
6354 .vendor_id = QCA_NL80211_VENDOR_ID,
6355 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6356 },
6357 {
6358 .vendor_id = QCA_NL80211_VENDOR_ID,
6359 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6360 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306361 {
6362 .vendor_id = QCA_NL80211_VENDOR_ID,
6363 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6364 },
6365 {
6366 .vendor_id = QCA_NL80211_VENDOR_ID,
6367 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6368 },
6369 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6370 .vendor_id = QCA_NL80211_VENDOR_ID,
6371 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6372 },
6373 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6374 .vendor_id = QCA_NL80211_VENDOR_ID,
6375 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6376 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306377#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306378/*EXT TDLS*/
6379 {
6380 .vendor_id = QCA_NL80211_VENDOR_ID,
6381 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6382 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306383 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6384 .vendor_id = QCA_NL80211_VENDOR_ID,
6385 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6386 },
6387
Srinivas Dasari030bad32015-02-18 23:23:54 +05306388
6389 {
6390 .vendor_id = QCA_NL80211_VENDOR_ID,
6391 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6392 },
6393
Sushant Kaushik084f6592015-09-10 13:11:56 +05306394 {
6395 .vendor_id = QCA_NL80211_VENDOR_ID,
6396 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6397 }
6398
6399
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006400};
6401
Jeff Johnson295189b2012-06-20 16:38:30 -07006402/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306403 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306404 * This function is called by hdd_wlan_startup()
6405 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306406 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306408struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006409{
6410 struct wiphy *wiphy;
6411 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306412 /*
6413 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 */
6415 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6416
6417 if (!wiphy)
6418 {
6419 /* Print error and jump into err label and free the memory */
6420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6421 return NULL;
6422 }
6423
Sunil Duttc69bccb2014-05-26 21:30:20 +05306424
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 return wiphy;
6426}
6427
6428/*
6429 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306430 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 * private ioctl to change the band value
6432 */
6433int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6434{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306435 int i, j;
6436 eNVChannelEnabledType channelEnabledState;
6437
Jeff Johnsone7245742012-09-05 17:12:55 -07006438 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306439
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306440 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306442
6443 if (NULL == wiphy->bands[i])
6444 {
6445 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6446 __func__, i);
6447 continue;
6448 }
6449
6450 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6451 {
6452 struct ieee80211_supported_band *band = wiphy->bands[i];
6453
6454 channelEnabledState = vos_nv_getChannelEnabledState(
6455 band->channels[j].hw_value);
6456
6457 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6458 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306459 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306460 continue;
6461 }
6462 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6463 {
6464 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6465 continue;
6466 }
6467
6468 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6469 NV_CHANNEL_INVALID == channelEnabledState)
6470 {
6471 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6472 }
6473 else if (NV_CHANNEL_DFS == channelEnabledState)
6474 {
6475 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6476 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6477 }
6478 else
6479 {
6480 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6481 |IEEE80211_CHAN_RADAR);
6482 }
6483 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 }
6485 return 0;
6486}
6487/*
6488 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306489 * This function is called by hdd_wlan_startup()
6490 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 * This function is used to initialize and register wiphy structure.
6492 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306493int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 struct wiphy *wiphy,
6495 hdd_config_t *pCfg
6496 )
6497{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306498 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306499 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6500
Jeff Johnsone7245742012-09-05 17:12:55 -07006501 ENTER();
6502
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 /* Now bind the underlying wlan device with wiphy */
6504 set_wiphy_dev(wiphy, dev);
6505
6506 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006507
Kiet Lam6c583332013-10-14 05:37:09 +05306508#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006509 /* the flag for the other case would be initialzed in
6510 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006511 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306512#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006513
Amar Singhalfddc28c2013-09-05 13:03:40 -07006514 /* This will disable updating of NL channels from passive to
6515 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6517 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6518#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006519 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306520#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006521
Amar Singhala49cbc52013-10-08 18:37:44 -07006522
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006524 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6525 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6526 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006527 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6529 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6530#else
6531 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6532#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006533#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006534
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006535#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006536 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006537#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006538 || pCfg->isFastRoamIniFeatureEnabled
6539#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006540#ifdef FEATURE_WLAN_ESE
6541 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006542#endif
6543 )
6544 {
6545 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6546 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006547#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006548#ifdef FEATURE_WLAN_TDLS
6549 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6550 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6551#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306552#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306553 if (pCfg->configPNOScanSupport)
6554 {
6555 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6556 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6557 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6558 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6559 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306560#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006561
Abhishek Singh10d85972015-04-17 10:27:23 +05306562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6563 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6564#endif
6565
Amar Singhalfddc28c2013-09-05 13:03:40 -07006566#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006567 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6568 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006569 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006570 driver need to determine what to do with both
6571 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006572
6573 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006574#else
6575 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006576#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306578 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6579
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306580 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006581
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306582 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6583
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306585 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6586 | BIT(NL80211_IFTYPE_ADHOC)
6587 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6588 | BIT(NL80211_IFTYPE_P2P_GO)
6589 | BIT(NL80211_IFTYPE_AP);
6590
6591 if (VOS_MONITOR_MODE == hdd_get_conparam())
6592 {
6593 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6594 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006595
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306596 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006597 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6599 if( pCfg->enableMCC )
6600 {
6601 /* Currently, supports up to two channels */
6602 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006603
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306604 if( !pCfg->allowMCCGODiffBI )
6605 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006606
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306607 }
6608 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6609 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006610#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306611 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006612
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 /* Before registering we need to update the ht capabilitied based
6614 * on ini values*/
6615 if( !pCfg->ShortGI20MhzEnable )
6616 {
6617 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6618 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6619 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6620 }
6621
6622 if( !pCfg->ShortGI40MhzEnable )
6623 {
6624 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6625 }
6626
6627 if( !pCfg->nChannelBondingMode5GHz )
6628 {
6629 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6630 }
6631
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306632 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306633 if (true == hdd_is_5g_supported(pHddCtx))
6634 {
6635 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6636 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306637
6638 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6639 {
6640
6641 if (NULL == wiphy->bands[i])
6642 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306643 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306644 __func__, i);
6645 continue;
6646 }
6647
6648 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6649 {
6650 struct ieee80211_supported_band *band = wiphy->bands[i];
6651
6652 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6653 {
6654 // Enable social channels for P2P
6655 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6656 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6657 else
6658 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6659 continue;
6660 }
6661 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6662 {
6663 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6664 continue;
6665 }
6666 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 /*Initialise the supported cipher suite details*/
6669 wiphy->cipher_suites = hdd_cipher_suites;
6670 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6671
6672 /*signal strength in mBm (100*dBm) */
6673 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6674
6675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306676 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006678
Sunil Duttc69bccb2014-05-26 21:30:20 +05306679 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6680 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006681 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6682 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6683
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306684 EXIT();
6685 return 0;
6686}
6687
6688/* In this function we are registering wiphy. */
6689int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6690{
6691 ENTER();
6692 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 if (0 > wiphy_register(wiphy))
6694 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306695 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6697 return -EIO;
6698 }
6699
6700 EXIT();
6701 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306702}
Jeff Johnson295189b2012-06-20 16:38:30 -07006703
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306704/* In this function we are updating channel list when,
6705 regulatory domain is FCC and country code is US.
6706 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6707 As per FCC smart phone is not a indoor device.
6708 GO should not opeate on indoor channels */
6709void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6710{
6711 int j;
6712 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6713 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6714 //Default counrtycode from NV at the time of wiphy initialization.
6715 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6716 &defaultCountryCode[0]))
6717 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006718 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306719 }
6720 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6721 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306722 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6723 {
6724 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6725 return;
6726 }
6727 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6728 {
6729 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6730 // Mark UNII -1 band channel as passive
6731 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6732 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6733 }
6734 }
6735}
6736
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306737/* This function registers for all frame which supplicant is interested in */
6738void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006739{
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6741 /* Register for all P2P action, public action etc frames */
6742 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6743
Jeff Johnsone7245742012-09-05 17:12:55 -07006744 ENTER();
6745
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 /* Right now we are registering these frame when driver is getting
6747 initialized. Once we will move to 2.6.37 kernel, in which we have
6748 frame register ops, we will move this code as a part of that */
6749 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6752
6753 /* GAS Initial Response */
6754 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6755 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306756
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 /* GAS Comeback Request */
6758 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6759 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6760
6761 /* GAS Comeback Response */
6762 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6763 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6764
6765 /* P2P Public Action */
6766 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306767 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 P2P_PUBLIC_ACTION_FRAME_SIZE );
6769
6770 /* P2P Action */
6771 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6772 (v_U8_t*)P2P_ACTION_FRAME,
6773 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006774
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306775 /* WNM BSS Transition Request frame */
6776 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6777 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6778 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006779
6780 /* WNM-Notification */
6781 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6782 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6783 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006784}
6785
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306786void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006787{
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6789 /* Register for all P2P action, public action etc frames */
6790 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6791
Jeff Johnsone7245742012-09-05 17:12:55 -07006792 ENTER();
6793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 /* Right now we are registering these frame when driver is getting
6795 initialized. Once we will move to 2.6.37 kernel, in which we have
6796 frame register ops, we will move this code as a part of that */
6797 /* GAS Initial Request */
6798
6799 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6800 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6801
6802 /* GAS Initial Response */
6803 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6804 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306805
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 /* GAS Comeback Request */
6807 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6808 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6809
6810 /* GAS Comeback Response */
6811 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6812 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6813
6814 /* P2P Public Action */
6815 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306816 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 P2P_PUBLIC_ACTION_FRAME_SIZE );
6818
6819 /* P2P Action */
6820 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6821 (v_U8_t*)P2P_ACTION_FRAME,
6822 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006823 /* WNM-Notification */
6824 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6825 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6826 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006827}
6828
6829#ifdef FEATURE_WLAN_WAPI
6830void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306831 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006832{
6833 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6834 tCsrRoamSetKey setKey;
6835 v_BOOL_t isConnected = TRUE;
6836 int status = 0;
6837 v_U32_t roamId= 0xFF;
6838 tANI_U8 *pKeyPtr = NULL;
6839 int n = 0;
6840
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6842 __func__, hdd_device_modetoString(pAdapter->device_mode),
6843 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306845 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 setKey.keyId = key_index; // Store Key ID
6847 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6848 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6849 setKey.paeRole = 0 ; // the PAE role
6850 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6851 {
6852 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6853 }
6854 else
6855 {
6856 isConnected = hdd_connIsConnected(pHddStaCtx);
6857 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6858 }
6859 setKey.keyLength = key_Len;
6860 pKeyPtr = setKey.Key;
6861 memcpy( pKeyPtr, key, key_Len);
6862
Arif Hussain6d2a3322013-11-17 19:50:10 -08006863 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 __func__, key_Len);
6865 for (n = 0 ; n < key_Len; n++)
6866 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6867 __func__,n,setKey.Key[n]);
6868
6869 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6870 if ( isConnected )
6871 {
6872 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6873 pAdapter->sessionId, &setKey, &roamId );
6874 }
6875 if ( status != 0 )
6876 {
6877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6878 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6879 __LINE__, status );
6880 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6881 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306882 /* Need to clear any trace of key value in the memory.
6883 * Thus zero out the memory even though it is local
6884 * variable.
6885 */
6886 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006887}
6888#endif /* FEATURE_WLAN_WAPI*/
6889
6890#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306891int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 beacon_data_t **ppBeacon,
6893 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006894#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306895int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006896 beacon_data_t **ppBeacon,
6897 struct cfg80211_beacon_data *params,
6898 int dtim_period)
6899#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306900{
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 int size;
6902 beacon_data_t *beacon = NULL;
6903 beacon_data_t *old = NULL;
6904 int head_len,tail_len;
6905
Jeff Johnsone7245742012-09-05 17:12:55 -07006906 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306908 {
6909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6910 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006913
6914 old = pAdapter->sessionCtx.ap.beacon;
6915
6916 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306917 {
6918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6919 FL("session(%d) old and new heads points to NULL"),
6920 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306922 }
6923
6924 if (params->tail && !params->tail_len)
6925 {
6926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6927 FL("tail_len is zero but tail is not NULL"));
6928 return -EINVAL;
6929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006930
Jeff Johnson295189b2012-06-20 16:38:30 -07006931#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6932 /* Kernel 3.0 is not updating dtim_period for set beacon */
6933 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306934 {
6935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6936 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006939#endif
6940
6941 if(params->head)
6942 head_len = params->head_len;
6943 else
6944 head_len = old->head_len;
6945
6946 if(params->tail || !old)
6947 tail_len = params->tail_len;
6948 else
6949 tail_len = old->tail_len;
6950
6951 size = sizeof(beacon_data_t) + head_len + tail_len;
6952
6953 beacon = kzalloc(size, GFP_KERNEL);
6954
6955 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306956 {
6957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6958 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006961
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 if(params->dtim_period || !old )
6964 beacon->dtim_period = params->dtim_period;
6965 else
6966 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006967#else
6968 if(dtim_period || !old )
6969 beacon->dtim_period = dtim_period;
6970 else
6971 beacon->dtim_period = old->dtim_period;
6972#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306973
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6975 beacon->tail = beacon->head + head_len;
6976 beacon->head_len = head_len;
6977 beacon->tail_len = tail_len;
6978
6979 if(params->head) {
6980 memcpy (beacon->head,params->head,beacon->head_len);
6981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 if(old)
6984 memcpy (beacon->head,old->head,beacon->head_len);
6985 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 if(params->tail) {
6988 memcpy (beacon->tail,params->tail,beacon->tail_len);
6989 }
6990 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 memcpy (beacon->tail,old->tail,beacon->tail_len);
6993 }
6994
6995 *ppBeacon = beacon;
6996
6997 kfree(old);
6998
6999 return 0;
7000
7001}
Jeff Johnson295189b2012-06-20 16:38:30 -07007002
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307003v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
7004#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7005 const v_U8_t *pIes,
7006#else
7007 v_U8_t *pIes,
7008#endif
7009 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007010{
7011 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307012 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307014
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307016 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 elem_id = ptr[0];
7018 elem_len = ptr[1];
7019 left -= 2;
7020 if(elem_len > left)
7021 {
7022 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007023 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 eid,elem_len,left);
7025 return NULL;
7026 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307027 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 {
7029 return ptr;
7030 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307031
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 left -= elem_len;
7033 ptr += (elem_len + 2);
7034 }
7035 return NULL;
7036}
7037
Jeff Johnson295189b2012-06-20 16:38:30 -07007038/* Check if rate is 11g rate or not */
7039static int wlan_hdd_rate_is_11g(u8 rate)
7040{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007041 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 u8 i;
7043 for (i = 0; i < 8; i++)
7044 {
7045 if(rate == gRateArray[i])
7046 return TRUE;
7047 }
7048 return FALSE;
7049}
7050
7051/* Check for 11g rate and set proper 11g only mode */
7052static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7053 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7054{
7055 u8 i, num_rates = pIe[0];
7056
7057 pIe += 1;
7058 for ( i = 0; i < num_rates; i++)
7059 {
7060 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7061 {
7062 /* If rate set have 11g rate than change the mode to 11G */
7063 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7064 if (pIe[i] & BASIC_RATE_MASK)
7065 {
7066 /* If we have 11g rate as basic rate, it means mode
7067 is 11g only mode.
7068 */
7069 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7070 *pCheckRatesfor11g = FALSE;
7071 }
7072 }
7073 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7074 {
7075 *require_ht = TRUE;
7076 }
7077 }
7078 return;
7079}
7080
7081static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7082{
7083 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7084 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7085 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7086 u8 checkRatesfor11g = TRUE;
7087 u8 require_ht = FALSE;
7088 u8 *pIe=NULL;
7089
7090 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7091
7092 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7093 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7094 if (pIe != NULL)
7095 {
7096 pIe += 1;
7097 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7098 &pConfig->SapHw_mode);
7099 }
7100
7101 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7102 WLAN_EID_EXT_SUPP_RATES);
7103 if (pIe != NULL)
7104 {
7105
7106 pIe += 1;
7107 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7108 &pConfig->SapHw_mode);
7109 }
7110
7111 if( pConfig->channel > 14 )
7112 {
7113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7114 }
7115
7116 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7117 WLAN_EID_HT_CAPABILITY);
7118
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307119 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 {
7121 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7122 if(require_ht)
7123 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7124 }
7125}
7126
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307127static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7128 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7129{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007130 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307131 v_U8_t *pIe = NULL;
7132 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7133
7134 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7135 pBeacon->tail, pBeacon->tail_len);
7136
7137 if (pIe)
7138 {
7139 ielen = pIe[1] + 2;
7140 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7141 {
7142 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7143 }
7144 else
7145 {
7146 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7147 return -EINVAL;
7148 }
7149 *total_ielen += ielen;
7150 }
7151 return 0;
7152}
7153
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007154static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7155 v_U8_t *genie, v_U8_t *total_ielen)
7156{
7157 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7158 int left = pBeacon->tail_len;
7159 v_U8_t *ptr = pBeacon->tail;
7160 v_U8_t elem_id, elem_len;
7161 v_U16_t ielen = 0;
7162
7163 if ( NULL == ptr || 0 == left )
7164 return;
7165
7166 while (left >= 2)
7167 {
7168 elem_id = ptr[0];
7169 elem_len = ptr[1];
7170 left -= 2;
7171 if (elem_len > left)
7172 {
7173 hddLog( VOS_TRACE_LEVEL_ERROR,
7174 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7175 elem_id, elem_len, left);
7176 return;
7177 }
7178 if (IE_EID_VENDOR == elem_id)
7179 {
7180 /* skipping the VSIE's which we don't want to include or
7181 * it will be included by existing code
7182 */
7183 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7184#ifdef WLAN_FEATURE_WFD
7185 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7186#endif
7187 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7188 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7189 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7190 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7191 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7192 {
7193 ielen = ptr[1] + 2;
7194 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7195 {
7196 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7197 *total_ielen += ielen;
7198 }
7199 else
7200 {
7201 hddLog( VOS_TRACE_LEVEL_ERROR,
7202 "IE Length is too big "
7203 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7204 elem_id, elem_len, *total_ielen);
7205 }
7206 }
7207 }
7208
7209 left -= elem_len;
7210 ptr += (elem_len + 2);
7211 }
7212 return;
7213}
7214
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007215#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007216static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7217 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007218#else
7219static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7220 struct cfg80211_beacon_data *params)
7221#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007222{
7223 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307224 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007226 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227
7228 genie = vos_mem_malloc(MAX_GENIE_LEN);
7229
7230 if(genie == NULL) {
7231
7232 return -ENOMEM;
7233 }
7234
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307235 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7236 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307238 hddLog(LOGE,
7239 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307240 ret = -EINVAL;
7241 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 }
7243
7244#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307245 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7246 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7247 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307248 hddLog(LOGE,
7249 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307250 ret = -EINVAL;
7251 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 }
7253#endif
7254
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307255 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7256 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307258 hddLog(LOGE,
7259 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307260 ret = -EINVAL;
7261 goto done;
7262 }
7263
7264 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7265 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007266 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007268
7269 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7270 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7271 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7272 {
7273 hddLog(LOGE,
7274 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007275 ret = -EINVAL;
7276 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 }
7278
7279 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7280 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7281 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7282 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7283 ==eHAL_STATUS_FAILURE)
7284 {
7285 hddLog(LOGE,
7286 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007287 ret = -EINVAL;
7288 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 }
7290
7291 // Added for ProResp IE
7292 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7293 {
7294 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7295 u8 probe_rsp_ie_len[3] = {0};
7296 u8 counter = 0;
7297 /* Check Probe Resp Length if it is greater then 255 then Store
7298 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7299 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7300 Store More then 255 bytes into One Variable.
7301 */
7302 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7303 {
7304 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7305 {
7306 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7307 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7308 }
7309 else
7310 {
7311 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7312 rem_probe_resp_ie_len = 0;
7313 }
7314 }
7315
7316 rem_probe_resp_ie_len = 0;
7317
7318 if (probe_rsp_ie_len[0] > 0)
7319 {
7320 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7321 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7322 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7323 probe_rsp_ie_len[0], NULL,
7324 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7325 {
7326 hddLog(LOGE,
7327 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007328 ret = -EINVAL;
7329 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007330 }
7331 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7332 }
7333
7334 if (probe_rsp_ie_len[1] > 0)
7335 {
7336 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7337 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7338 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7339 probe_rsp_ie_len[1], NULL,
7340 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7341 {
7342 hddLog(LOGE,
7343 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007344 ret = -EINVAL;
7345 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 }
7347 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7348 }
7349
7350 if (probe_rsp_ie_len[2] > 0)
7351 {
7352 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7353 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7354 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7355 probe_rsp_ie_len[2], NULL,
7356 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7357 {
7358 hddLog(LOGE,
7359 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007360 ret = -EINVAL;
7361 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 }
7363 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7364 }
7365
7366 if (probe_rsp_ie_len[1] == 0 )
7367 {
7368 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7369 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7370 eANI_BOOLEAN_FALSE) )
7371 {
7372 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007373 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 }
7375 }
7376
7377 if (probe_rsp_ie_len[2] == 0 )
7378 {
7379 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7380 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7381 eANI_BOOLEAN_FALSE) )
7382 {
7383 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007384 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 }
7386 }
7387
7388 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7389 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7390 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7391 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7392 == eHAL_STATUS_FAILURE)
7393 {
7394 hddLog(LOGE,
7395 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007396 ret = -EINVAL;
7397 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 }
7399 }
7400 else
7401 {
7402 // Reset WNI_CFG_PROBE_RSP Flags
7403 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7404
7405 hddLog(VOS_TRACE_LEVEL_INFO,
7406 "%s: No Probe Response IE received in set beacon",
7407 __func__);
7408 }
7409
7410 // Added for AssocResp IE
7411 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7412 {
7413 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7414 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7415 params->assocresp_ies_len, NULL,
7416 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7417 {
7418 hddLog(LOGE,
7419 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007420 ret = -EINVAL;
7421 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 }
7423
7424 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7425 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7426 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7427 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7428 == eHAL_STATUS_FAILURE)
7429 {
7430 hddLog(LOGE,
7431 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007432 ret = -EINVAL;
7433 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 }
7435 }
7436 else
7437 {
7438 hddLog(VOS_TRACE_LEVEL_INFO,
7439 "%s: No Assoc Response IE received in set beacon",
7440 __func__);
7441
7442 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7443 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7444 eANI_BOOLEAN_FALSE) )
7445 {
7446 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007447 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 }
7449 }
7450
Jeff Johnsone7245742012-09-05 17:12:55 -07007451done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307453 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007454}
Jeff Johnson295189b2012-06-20 16:38:30 -07007455
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307456/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 * FUNCTION: wlan_hdd_validate_operation_channel
7458 * called by wlan_hdd_cfg80211_start_bss() and
7459 * wlan_hdd_cfg80211_set_channel()
7460 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307461 * channel list.
7462 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007463VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007464{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307465
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 v_U32_t num_ch = 0;
7467 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7468 u32 indx = 0;
7469 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307470 v_U8_t fValidChannel = FALSE, count = 0;
7471 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307472
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7474
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307475 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307477 /* Validate the channel */
7478 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307480 if ( channel == rfChannels[count].channelNum )
7481 {
7482 fValidChannel = TRUE;
7483 break;
7484 }
7485 }
7486 if (fValidChannel != TRUE)
7487 {
7488 hddLog(VOS_TRACE_LEVEL_ERROR,
7489 "%s: Invalid Channel [%d]", __func__, channel);
7490 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 }
7492 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307493 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307495 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7496 valid_ch, &num_ch))
7497 {
7498 hddLog(VOS_TRACE_LEVEL_ERROR,
7499 "%s: failed to get valid channel list", __func__);
7500 return VOS_STATUS_E_FAILURE;
7501 }
7502 for (indx = 0; indx < num_ch; indx++)
7503 {
7504 if (channel == valid_ch[indx])
7505 {
7506 break;
7507 }
7508 }
7509
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307510 if (indx >= num_ch)
7511 {
7512 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7513 {
7514 eCsrBand band;
7515 unsigned int freq;
7516
7517 sme_GetFreqBand(hHal, &band);
7518
7519 if (eCSR_BAND_5G == band)
7520 {
7521#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7522 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7523 {
7524 freq = ieee80211_channel_to_frequency(channel,
7525 IEEE80211_BAND_2GHZ);
7526 }
7527 else
7528 {
7529 freq = ieee80211_channel_to_frequency(channel,
7530 IEEE80211_BAND_5GHZ);
7531 }
7532#else
7533 freq = ieee80211_channel_to_frequency(channel);
7534#endif
7535 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7536 return VOS_STATUS_SUCCESS;
7537 }
7538 }
7539
7540 hddLog(VOS_TRACE_LEVEL_ERROR,
7541 "%s: Invalid Channel [%d]", __func__, channel);
7542 return VOS_STATUS_E_FAILURE;
7543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307545
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307547
Jeff Johnson295189b2012-06-20 16:38:30 -07007548}
7549
Viral Modi3a32cc52013-02-08 11:14:52 -08007550/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307551 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007552 * This function is used to set the channel number
7553 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307554static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007555 struct ieee80211_channel *chan,
7556 enum nl80211_channel_type channel_type
7557 )
7558{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307559 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007560 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007561 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007562 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307563 hdd_context_t *pHddCtx;
7564 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007565
7566 ENTER();
7567
7568 if( NULL == dev )
7569 {
7570 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007571 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007572 return -ENODEV;
7573 }
7574 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307575
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307576 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7577 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7578 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007579 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307580 "%s: device_mode = %s (%d) freq = %d", __func__,
7581 hdd_device_modetoString(pAdapter->device_mode),
7582 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307583
7584 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7585 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307586 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007587 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307588 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007589 }
7590
7591 /*
7592 * Do freq to chan conversion
7593 * TODO: for 11a
7594 */
7595
7596 channel = ieee80211_frequency_to_channel(freq);
7597
7598 /* Check freq range */
7599 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7600 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7601 {
7602 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007603 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007604 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7605 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7606 return -EINVAL;
7607 }
7608
7609 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7610
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307611 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7612 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007613 {
7614 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7615 {
7616 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007617 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007618 return -EINVAL;
7619 }
7620 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7621 "%s: set channel to [%d] for device mode =%d",
7622 __func__, channel,pAdapter->device_mode);
7623 }
7624 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007625 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007626 )
7627 {
7628 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7629 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7630 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7631
7632 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7633 {
7634 /* Link is up then return cant set channel*/
7635 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007636 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007637 return -EINVAL;
7638 }
7639
7640 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7641 pHddStaCtx->conn_info.operationChannel = channel;
7642 pRoamProfile->ChannelInfo.ChannelList =
7643 &pHddStaCtx->conn_info.operationChannel;
7644 }
7645 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007646 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007647 )
7648 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307649 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7650 {
7651 if(VOS_STATUS_SUCCESS !=
7652 wlan_hdd_validate_operation_channel(pAdapter,channel))
7653 {
7654 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007655 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307656 return -EINVAL;
7657 }
7658 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7659 }
7660 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007661 {
7662 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7663
7664 /* If auto channel selection is configured as enable/ 1 then ignore
7665 channel set by supplicant
7666 */
7667 if ( cfg_param->apAutoChannelSelection )
7668 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307669 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7670 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307672 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7673 __func__, hdd_device_modetoString(pAdapter->device_mode),
7674 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007675 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307676 else
7677 {
7678 if(VOS_STATUS_SUCCESS !=
7679 wlan_hdd_validate_operation_channel(pAdapter,channel))
7680 {
7681 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007682 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307683 return -EINVAL;
7684 }
7685 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7686 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007687 }
7688 }
7689 else
7690 {
7691 hddLog(VOS_TRACE_LEVEL_FATAL,
7692 "%s: Invalid device mode failed to set valid channel", __func__);
7693 return -EINVAL;
7694 }
7695 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307696 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007697}
7698
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307699static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7700 struct net_device *dev,
7701 struct ieee80211_channel *chan,
7702 enum nl80211_channel_type channel_type
7703 )
7704{
7705 int ret;
7706
7707 vos_ssr_protect(__func__);
7708 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7709 vos_ssr_unprotect(__func__);
7710
7711 return ret;
7712}
7713
Jeff Johnson295189b2012-06-20 16:38:30 -07007714#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7715static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7716 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007717#else
7718static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7719 struct cfg80211_beacon_data *params,
7720 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307721 enum nl80211_hidden_ssid hidden_ssid,
7722 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007723#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007724{
7725 tsap_Config_t *pConfig;
7726 beacon_data_t *pBeacon = NULL;
7727 struct ieee80211_mgmt *pMgmt_frame;
7728 v_U8_t *pIe=NULL;
7729 v_U16_t capab_info;
7730 eCsrAuthType RSNAuthType;
7731 eCsrEncryptionType RSNEncryptType;
7732 eCsrEncryptionType mcRSNEncryptType;
7733 int status = VOS_STATUS_SUCCESS;
7734 tpWLAN_SAPEventCB pSapEventCallback;
7735 hdd_hostapd_state_t *pHostapdState;
7736 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7737 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307738 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307740 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007742 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307743 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007744 v_BOOL_t MFPCapable = VOS_FALSE;
7745 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307746 v_BOOL_t sapEnable11AC =
7747 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 ENTER();
7749
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307750 iniConfig = pHddCtx->cfg_ini;
7751
Jeff Johnson295189b2012-06-20 16:38:30 -07007752 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7753
7754 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7755
7756 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7757
7758 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7759
7760 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7761
7762 //channel is already set in the set_channel Call back
7763 //pConfig->channel = pCommitConfig->channel;
7764
7765 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307766 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7768
7769 pConfig->dtim_period = pBeacon->dtim_period;
7770
Arif Hussain6d2a3322013-11-17 19:50:10 -08007771 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 pConfig->dtim_period);
7773
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007774 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007775 {
7776 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307778 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7779 {
7780 tANI_BOOLEAN restartNeeded;
7781 pConfig->ieee80211d = 1;
7782 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7783 sme_setRegInfo(hHal, pConfig->countryCode);
7784 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7785 }
7786 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007788 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007789 pConfig->ieee80211d = 1;
7790 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7791 sme_setRegInfo(hHal, pConfig->countryCode);
7792 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007794 else
7795 {
7796 pConfig->ieee80211d = 0;
7797 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307798 /*
7799 * If auto channel is configured i.e. channel is 0,
7800 * so skip channel validation.
7801 */
7802 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7803 {
7804 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7805 {
7806 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007807 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307808 return -EINVAL;
7809 }
7810 }
7811 else
7812 {
7813 if(1 != pHddCtx->is_dynamic_channel_range_set)
7814 {
7815 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7816 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7817 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7818 }
7819 pHddCtx->is_dynamic_channel_range_set = 0;
7820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007821 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007822 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 {
7824 pConfig->ieee80211d = 0;
7825 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307826
7827#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7828 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7829 pConfig->authType = eSAP_OPEN_SYSTEM;
7830 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7831 pConfig->authType = eSAP_SHARED_KEY;
7832 else
7833 pConfig->authType = eSAP_AUTO_SWITCH;
7834#else
7835 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7836 pConfig->authType = eSAP_OPEN_SYSTEM;
7837 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7838 pConfig->authType = eSAP_SHARED_KEY;
7839 else
7840 pConfig->authType = eSAP_AUTO_SWITCH;
7841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007842
7843 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307844
7845 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7847
7848 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7849
7850 /*Set wps station to configured*/
7851 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7852
7853 if(pIe)
7854 {
7855 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7856 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007857 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 return -EINVAL;
7859 }
7860 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7861 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007862 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 /* Check 15 bit of WPS IE as it contain information for wps state
7864 * WPS state
7865 */
7866 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7867 {
7868 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7869 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7870 {
7871 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7872 }
7873 }
7874 }
7875 else
7876 {
7877 pConfig->wps_state = SAP_WPS_DISABLED;
7878 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307879 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007880
c_hpothufe599e92014-06-16 11:38:55 +05307881 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7882 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7883 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7884 eCSR_ENCRYPT_TYPE_NONE;
7885
Jeff Johnson295189b2012-06-20 16:38:30 -07007886 pConfig->RSNWPAReqIELength = 0;
7887 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307888 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 WLAN_EID_RSN);
7890 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307891 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7893 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7894 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307895 /* The actual processing may eventually be more extensive than
7896 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 * by the app.
7898 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307899 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007900 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7901 &RSNEncryptType,
7902 &mcRSNEncryptType,
7903 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007904 &MFPCapable,
7905 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007906 pConfig->pRSNWPAReqIE[1]+2,
7907 pConfig->pRSNWPAReqIE );
7908
7909 if( VOS_STATUS_SUCCESS == status )
7910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307911 /* Now copy over all the security attributes you have
7912 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 * */
7914 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7915 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7916 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7917 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307918 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007919 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7921 }
7922 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307923
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7925 pBeacon->tail, pBeacon->tail_len);
7926
7927 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7928 {
7929 if (pConfig->pRSNWPAReqIE)
7930 {
7931 /*Mixed mode WPA/WPA2*/
7932 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7933 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7934 }
7935 else
7936 {
7937 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7938 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7939 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307940 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7942 &RSNEncryptType,
7943 &mcRSNEncryptType,
7944 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007945 &MFPCapable,
7946 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 pConfig->pRSNWPAReqIE[1]+2,
7948 pConfig->pRSNWPAReqIE );
7949
7950 if( VOS_STATUS_SUCCESS == status )
7951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307952 /* Now copy over all the security attributes you have
7953 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 * */
7955 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7956 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7957 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7958 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307959 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007960 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7962 }
7963 }
7964 }
7965
Jeff Johnson4416a782013-03-25 14:17:50 -07007966 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7967 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7968 return -EINVAL;
7969 }
7970
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7972
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007973#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 if (params->ssid != NULL)
7975 {
7976 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7977 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7978 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7979 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7980 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007981#else
7982 if (ssid != NULL)
7983 {
7984 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7985 pConfig->SSIDinfo.ssid.length = ssid_len;
7986 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7987 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7988 }
7989#endif
7990
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307991 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 /* default value */
7995 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7996 pConfig->num_accept_mac = 0;
7997 pConfig->num_deny_mac = 0;
7998
7999 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8000 pBeacon->tail, pBeacon->tail_len);
8001
8002 /* pIe for black list is following form:
8003 type : 1 byte
8004 length : 1 byte
8005 OUI : 4 bytes
8006 acl type : 1 byte
8007 no of mac addr in black list: 1 byte
8008 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009 */
8010 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 {
8012 pConfig->SapMacaddr_acl = pIe[6];
8013 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008014 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308016 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8017 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8019 for (i = 0; i < pConfig->num_deny_mac; i++)
8020 {
8021 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8022 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 }
8025 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8026 pBeacon->tail, pBeacon->tail_len);
8027
8028 /* pIe for white list is following form:
8029 type : 1 byte
8030 length : 1 byte
8031 OUI : 4 bytes
8032 acl type : 1 byte
8033 no of mac addr in white list: 1 byte
8034 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308035 */
8036 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 {
8038 pConfig->SapMacaddr_acl = pIe[6];
8039 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008040 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308042 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8043 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8045 for (i = 0; i < pConfig->num_accept_mac; i++)
8046 {
8047 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8048 acl_entry++;
8049 }
8050 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308051
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8053
Jeff Johnsone7245742012-09-05 17:12:55 -07008054#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008055 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308056 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8057 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308058 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8059 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008060 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8061 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308062 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8063 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008064 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308065 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008066 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308067 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008068
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308069 /* If ACS disable and selected channel <= 14
8070 * OR
8071 * ACS enabled and ACS operating band is choosen as 2.4
8072 * AND
8073 * VHT in 2.4G Disabled
8074 * THEN
8075 * Fallback to 11N mode
8076 */
8077 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8078 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308079 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308080 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008081 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308082 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8083 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008084 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8085 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008086 }
8087#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308088
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 // ht_capab is not what the name conveys,this is used for protection bitmap
8090 pConfig->ht_capab =
8091 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8092
8093 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8094 {
8095 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8096 return -EINVAL;
8097 }
8098
8099 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308100 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008101 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8102 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308103 pConfig->obssProtEnabled =
8104 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008105
Chet Lanctot8cecea22014-02-11 19:09:36 -08008106#ifdef WLAN_FEATURE_11W
8107 pConfig->mfpCapable = MFPCapable;
8108 pConfig->mfpRequired = MFPRequired;
8109 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8110 pConfig->mfpCapable, pConfig->mfpRequired);
8111#endif
8112
Arif Hussain6d2a3322013-11-17 19:50:10 -08008113 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008115 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8116 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8117 (int)pConfig->channel);
8118 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8119 pConfig->SapHw_mode, pConfig->privacy,
8120 pConfig->authType);
8121 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8122 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8123 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8124 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008125
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308126 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 {
8128 //Bss already started. just return.
8129 //TODO Probably it should update some beacon params.
8130 hddLog( LOGE, "Bss Already started...Ignore the request");
8131 EXIT();
8132 return 0;
8133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308134
Agarwal Ashish51325b52014-06-16 16:50:49 +05308135 if (vos_max_concurrent_connections_reached()) {
8136 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8137 return -EINVAL;
8138 }
8139
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 pConfig->persona = pHostapdAdapter->device_mode;
8141
Peng Xu2446a892014-09-05 17:21:18 +05308142 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8143 if ( NULL != psmeConfig)
8144 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308145 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308146 sme_GetConfigParam(hHal, psmeConfig);
8147 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308148#ifdef WLAN_FEATURE_AP_HT40_24G
8149 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8150 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8151 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8152 {
8153 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8154 sme_UpdateConfig (hHal, psmeConfig);
8155 }
8156#endif
Peng Xu2446a892014-09-05 17:21:18 +05308157 vos_mem_free(psmeConfig);
8158 }
Peng Xuafc34e32014-09-25 13:23:55 +05308159 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308160
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 pSapEventCallback = hdd_hostapd_SAPEventCB;
8162 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8163 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8164 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008165 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 return -EINVAL;
8167 }
8168
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308169 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008170 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8171
8172 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308173
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175 {
8176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008177 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008178 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 VOS_ASSERT(0);
8180 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308181
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308183 /* Initialize WMM configuation */
8184 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308185 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008186
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008187#ifdef WLAN_FEATURE_P2P_DEBUG
8188 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8189 {
8190 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8191 {
8192 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8193 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008194 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008195 }
8196 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8197 {
8198 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8199 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008200 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008201 }
8202 }
8203#endif
8204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 pHostapdState->bCommit = TRUE;
8206 EXIT();
8207
8208 return 0;
8209}
8210
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008211#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308212static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 struct beacon_parameters *params)
8215{
8216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308217 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308218 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008219
8220 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308221
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308222 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8223 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8224 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308225 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8226 hdd_device_modetoString(pAdapter->device_mode),
8227 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308229 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8230 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308231 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008232 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308233 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008234 }
8235
Agarwal Ashish51325b52014-06-16 16:50:49 +05308236 if (vos_max_concurrent_connections_reached()) {
8237 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8238 return -EINVAL;
8239 }
8240
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308241 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 )
8244 {
8245 beacon_data_t *old,*new;
8246
8247 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308248
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308250 {
8251 hddLog(VOS_TRACE_LEVEL_WARN,
8252 FL("already beacon info added to session(%d)"),
8253 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308255 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008256
8257 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8258
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308259 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 {
8261 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008262 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 return -EINVAL;
8264 }
8265
8266 pAdapter->sessionCtx.ap.beacon = new;
8267
8268 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8269 }
8270
8271 EXIT();
8272 return status;
8273}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308274
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308275static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8276 struct net_device *dev,
8277 struct beacon_parameters *params)
8278{
8279 int ret;
8280
8281 vos_ssr_protect(__func__);
8282 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8283 vos_ssr_unprotect(__func__);
8284
8285 return ret;
8286}
8287
8288static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 struct net_device *dev,
8290 struct beacon_parameters *params)
8291{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308293 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8294 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308295 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008296
8297 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308298
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308299 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8300 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8301 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8303 __func__, hdd_device_modetoString(pAdapter->device_mode),
8304 pAdapter->device_mode);
8305
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308306 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8307 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308308 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008309 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308310 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308312
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308313 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308315 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 {
8317 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308318
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308320
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308322 {
8323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8324 FL("session(%d) old and new heads points to NULL"),
8325 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008326 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008328
8329 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8330
8331 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308332 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008333 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 return -EINVAL;
8335 }
8336
8337 pAdapter->sessionCtx.ap.beacon = new;
8338
8339 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8340 }
8341
8342 EXIT();
8343 return status;
8344}
8345
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308346static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8347 struct net_device *dev,
8348 struct beacon_parameters *params)
8349{
8350 int ret;
8351
8352 vos_ssr_protect(__func__);
8353 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8354 vos_ssr_unprotect(__func__);
8355
8356 return ret;
8357}
8358
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008359#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8360
8361#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308362static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008364#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308365static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008366 struct net_device *dev)
8367#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008368{
8369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008370 hdd_context_t *pHddCtx = NULL;
8371 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308372 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308373 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008374
8375 ENTER();
8376
8377 if (NULL == pAdapter)
8378 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008380 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008381 return -ENODEV;
8382 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008383
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8385 TRACE_CODE_HDD_CFG80211_STOP_AP,
8386 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308387 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8388 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308389 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008390 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308391 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008392 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008393
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008394 pScanInfo = &pHddCtx->scan_info;
8395
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8397 __func__, hdd_device_modetoString(pAdapter->device_mode),
8398 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008399
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308400 ret = wlan_hdd_scan_abort(pAdapter);
8401
Girish Gowli4bf7a632014-06-12 13:42:11 +05308402 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008403 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8405 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308406
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308407 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008408 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8410 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008411
Jeff Johnsone7245742012-09-05 17:12:55 -07008412 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308413 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008414 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308415 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008416 }
8417
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308418 /* Delete all associated STAs before stopping AP/P2P GO */
8419 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308420 hdd_hostapd_stop(dev);
8421
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 )
8425 {
8426 beacon_data_t *old;
8427
8428 old = pAdapter->sessionCtx.ap.beacon;
8429
8430 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308431 {
8432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8433 FL("session(%d) beacon data points to NULL"),
8434 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008437
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008439
8440 mutex_lock(&pHddCtx->sap_lock);
8441 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8442 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008443 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 {
8445 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8446
8447 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8448
8449 if (!VOS_IS_STATUS_SUCCESS(status))
8450 {
8451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008452 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308454 }
8455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308457 /* BSS stopped, clear the active sessions for this device mode */
8458 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 }
8460 mutex_unlock(&pHddCtx->sap_lock);
8461
8462 if(status != VOS_STATUS_SUCCESS)
8463 {
8464 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008465 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 return -EINVAL;
8467 }
8468
Jeff Johnson4416a782013-03-25 14:17:50 -07008469 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8471 ==eHAL_STATUS_FAILURE)
8472 {
8473 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008474 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 }
8476
Jeff Johnson4416a782013-03-25 14:17:50 -07008477 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8479 eANI_BOOLEAN_FALSE) )
8480 {
8481 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008482 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 }
8484
8485 // Reset WNI_CFG_PROBE_RSP Flags
8486 wlan_hdd_reset_prob_rspies(pAdapter);
8487
8488 pAdapter->sessionCtx.ap.beacon = NULL;
8489 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008490#ifdef WLAN_FEATURE_P2P_DEBUG
8491 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8492 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8493 {
8494 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8495 "GO got removed");
8496 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8497 }
8498#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 }
8500 EXIT();
8501 return status;
8502}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008503
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8505static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8506 struct net_device *dev)
8507{
8508 int ret;
8509
8510 vos_ssr_protect(__func__);
8511 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8512 vos_ssr_unprotect(__func__);
8513
8514 return ret;
8515}
8516#else
8517static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8518 struct net_device *dev)
8519{
8520 int ret;
8521
8522 vos_ssr_protect(__func__);
8523 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8524 vos_ssr_unprotect(__func__);
8525
8526 return ret;
8527}
8528#endif
8529
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008530#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8531
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308532static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308533 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008534 struct cfg80211_ap_settings *params)
8535{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308536 hdd_adapter_t *pAdapter;
8537 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308538 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008539
8540 ENTER();
8541
Girish Gowlib143d7a2015-02-18 19:39:55 +05308542 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008543 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308545 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308546 return -ENODEV;
8547 }
8548
8549 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8550 if (NULL == pAdapter)
8551 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308553 "%s: HDD adapter is Null", __func__);
8554 return -ENODEV;
8555 }
8556
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308557 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8558 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8559 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308560 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308563 "%s: HDD adapter magic is invalid", __func__);
8564 return -ENODEV;
8565 }
8566
8567 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308568 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308569 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308570 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308571 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308572 }
8573
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308574 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8575 __func__, hdd_device_modetoString(pAdapter->device_mode),
8576 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308577
8578 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008579 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008580 )
8581 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308582 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008583
8584 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308585
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008586 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308587 {
8588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8589 FL("already beacon info added to session(%d)"),
8590 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008591 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308592 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008593
Girish Gowlib143d7a2015-02-18 19:39:55 +05308594#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8595 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8596 &new,
8597 &params->beacon);
8598#else
8599 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8600 &new,
8601 &params->beacon,
8602 params->dtim_period);
8603#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008604
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308605 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008606 {
8607 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308608 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008609 return -EINVAL;
8610 }
8611 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008613 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8614#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8615 params->channel, params->channel_type);
8616#else
8617 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8618#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008619#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008620 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308621 params->ssid_len, params->hidden_ssid,
8622 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008623 }
8624
8625 EXIT();
8626 return status;
8627}
8628
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308629static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8630 struct net_device *dev,
8631 struct cfg80211_ap_settings *params)
8632{
8633 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008634
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308635 vos_ssr_protect(__func__);
8636 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8637 vos_ssr_unprotect(__func__);
8638
8639 return ret;
8640}
8641
8642static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008643 struct net_device *dev,
8644 struct cfg80211_beacon_data *params)
8645{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308647 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308648 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008649
8650 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308651
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8653 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8654 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008656 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308657
8658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308660 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308662 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008663 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008664
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308665 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008666 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308667 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008668 {
8669 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308670
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008671 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308672
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008673 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308674 {
8675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8676 FL("session(%d) beacon data points to NULL"),
8677 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008678 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308679 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008680
8681 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8682
8683 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308684 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008685 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008686 return -EINVAL;
8687 }
8688
8689 pAdapter->sessionCtx.ap.beacon = new;
8690
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308691 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8692 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008693 }
8694
8695 EXIT();
8696 return status;
8697}
8698
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308699static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8700 struct net_device *dev,
8701 struct cfg80211_beacon_data *params)
8702{
8703 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008704
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308705 vos_ssr_protect(__func__);
8706 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8707 vos_ssr_unprotect(__func__);
8708
8709 return ret;
8710}
8711
8712#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008713
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308714static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008715 struct net_device *dev,
8716 struct bss_parameters *params)
8717{
8718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308719 hdd_context_t *pHddCtx;
8720 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008721
8722 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308723
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308724 if (NULL == pAdapter)
8725 {
8726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8727 "%s: HDD adapter is Null", __func__);
8728 return -ENODEV;
8729 }
8730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308731 ret = wlan_hdd_validate_context(pHddCtx);
8732 if (0 != ret)
8733 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308734 return ret;
8735 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8737 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8738 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8740 __func__, hdd_device_modetoString(pAdapter->device_mode),
8741 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008742
8743 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308745 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 {
8747 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8748 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308749 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 {
8751 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308752 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 }
8754
8755 EXIT();
8756 return 0;
8757}
8758
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308759static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8760 struct net_device *dev,
8761 struct bss_parameters *params)
8762{
8763 int ret;
8764
8765 vos_ssr_protect(__func__);
8766 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8767 vos_ssr_unprotect(__func__);
8768
8769 return ret;
8770}
Kiet Lam10841362013-11-01 11:36:50 +05308771/* FUNCTION: wlan_hdd_change_country_code_cd
8772* to wait for contry code completion
8773*/
8774void* wlan_hdd_change_country_code_cb(void *pAdapter)
8775{
8776 hdd_adapter_t *call_back_pAdapter = pAdapter;
8777 complete(&call_back_pAdapter->change_country_code);
8778 return NULL;
8779}
8780
Jeff Johnson295189b2012-06-20 16:38:30 -07008781/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308782 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8784 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308785int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 struct net_device *ndev,
8787 enum nl80211_iftype type,
8788 u32 *flags,
8789 struct vif_params *params
8790 )
8791{
8792 struct wireless_dev *wdev;
8793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008794 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008795 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 tCsrRoamProfile *pRoamProfile = NULL;
8797 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308798 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 eMib_dot11DesiredBssType connectedBssType;
8800 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308801 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008802
8803 ENTER();
8804
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308805 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008806 {
8807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8808 "%s: Adapter context is null", __func__);
8809 return VOS_STATUS_E_FAILURE;
8810 }
8811
8812 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8813 if (!pHddCtx)
8814 {
8815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8816 "%s: HDD context is null", __func__);
8817 return VOS_STATUS_E_FAILURE;
8818 }
8819
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8821 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8822 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308823 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308824 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308826 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 }
8828
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8830 __func__, hdd_device_modetoString(pAdapter->device_mode),
8831 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008832
Agarwal Ashish51325b52014-06-16 16:50:49 +05308833 if (vos_max_concurrent_connections_reached()) {
8834 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8835 return -EINVAL;
8836 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308837 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 wdev = ndev->ieee80211_ptr;
8839
8840#ifdef WLAN_BTAMP_FEATURE
8841 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8842 (NL80211_IFTYPE_ADHOC == type)||
8843 (NL80211_IFTYPE_AP == type)||
8844 (NL80211_IFTYPE_P2P_GO == type))
8845 {
8846 pHddCtx->isAmpAllowed = VOS_FALSE;
8847 // stop AMP traffic
8848 status = WLANBAP_StopAmp();
8849 if(VOS_STATUS_SUCCESS != status )
8850 {
8851 pHddCtx->isAmpAllowed = VOS_TRUE;
8852 hddLog(VOS_TRACE_LEVEL_FATAL,
8853 "%s: Failed to stop AMP", __func__);
8854 return -EINVAL;
8855 }
8856 }
8857#endif //WLAN_BTAMP_FEATURE
8858 /* Reset the current device mode bit mask*/
8859 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8860
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308861 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8862 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8863 (type == NL80211_IFTYPE_P2P_GO)))
8864 {
8865 /* Notify Mode change in case of concurrency.
8866 * Below function invokes TDLS teardown Functionality Since TDLS is
8867 * not Supported in case of concurrency i.e Once P2P session
8868 * is detected disable offchannel and teardown TDLS links
8869 */
8870 hddLog(LOG1,
8871 FL("Device mode = %d Interface type = %d"),
8872 pAdapter->device_mode, type);
8873 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8874 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008878 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 )
8880 {
8881 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008882 if (!pWextState)
8883 {
8884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8885 "%s: pWextState is null", __func__);
8886 return VOS_STATUS_E_FAILURE;
8887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 pRoamProfile = &pWextState->roamProfile;
8889 LastBSSType = pRoamProfile->BSSType;
8890
8891 switch (type)
8892 {
8893 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 hddLog(VOS_TRACE_LEVEL_INFO,
8896 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8897 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008898#ifdef WLAN_FEATURE_11AC
8899 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8900 {
8901 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8902 }
8903#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308904 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008905 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008907 //Check for sub-string p2p to confirm its a p2p interface
8908 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308909 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308910#ifdef FEATURE_WLAN_TDLS
8911 mutex_lock(&pHddCtx->tdls_lock);
8912 wlan_hdd_tdls_exit(pAdapter, TRUE);
8913 mutex_unlock(&pHddCtx->tdls_lock);
8914#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008915 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8916 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8917 }
8918 else
8919 {
8920 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308924
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 case NL80211_IFTYPE_ADHOC:
8926 hddLog(VOS_TRACE_LEVEL_INFO,
8927 "%s: setting interface Type to ADHOC", __func__);
8928 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8929 pRoamProfile->phyMode =
8930 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008931 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308933 hdd_set_ibss_ops( pAdapter );
8934 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308935
8936 status = hdd_sta_id_hash_attach(pAdapter);
8937 if (VOS_STATUS_SUCCESS != status) {
8938 hddLog(VOS_TRACE_LEVEL_ERROR,
8939 FL("Failed to initialize hash for IBSS"));
8940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 break;
8942
8943 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 {
8946 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8947 "%s: setting interface Type to %s", __func__,
8948 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8949
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008950 //Cancel any remain on channel for GO mode
8951 if (NL80211_IFTYPE_P2P_GO == type)
8952 {
8953 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8954 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008955 if (NL80211_IFTYPE_AP == type)
8956 {
8957 /* As Loading WLAN Driver one interface being created for p2p device
8958 * address. This will take one HW STA and the max number of clients
8959 * that can connect to softAP will be reduced by one. so while changing
8960 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8961 * interface as it is not required in SoftAP mode.
8962 */
8963
8964 // Get P2P Adapter
8965 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8966
8967 if (pP2pAdapter)
8968 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308969 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308970 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008971 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8972 }
8973 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308974 //Disable IMPS & BMPS for SAP/GO
8975 if(VOS_STATUS_E_FAILURE ==
8976 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8977 {
8978 //Fail to Exit BMPS
8979 VOS_ASSERT(0);
8980 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308981
8982 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8983
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308984#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008985
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308986 /* A Mutex Lock is introduced while changing the mode to
8987 * protect the concurrent access for the Adapters by TDLS
8988 * module.
8989 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308990 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308991#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308993 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8996 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308997#ifdef FEATURE_WLAN_TDLS
8998 mutex_unlock(&pHddCtx->tdls_lock);
8999#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009000 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
9001 (pConfig->apRandomBssidEnabled))
9002 {
9003 /* To meet Android requirements create a randomized
9004 MAC address of the form 02:1A:11:Fx:xx:xx */
9005 get_random_bytes(&ndev->dev_addr[3], 3);
9006 ndev->dev_addr[0] = 0x02;
9007 ndev->dev_addr[1] = 0x1A;
9008 ndev->dev_addr[2] = 0x11;
9009 ndev->dev_addr[3] |= 0xF0;
9010 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9011 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009012 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9013 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009014 }
9015
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 hdd_set_ap_ops( pAdapter->dev );
9017
Kiet Lam10841362013-11-01 11:36:50 +05309018 /* This is for only SAP mode where users can
9019 * control country through ini.
9020 * P2P GO follows station country code
9021 * acquired during the STA scanning. */
9022 if((NL80211_IFTYPE_AP == type) &&
9023 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9024 {
9025 int status = 0;
9026 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9027 "%s: setting country code from INI ", __func__);
9028 init_completion(&pAdapter->change_country_code);
9029 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9030 (void *)(tSmeChangeCountryCallback)
9031 wlan_hdd_change_country_code_cb,
9032 pConfig->apCntryCode, pAdapter,
9033 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309034 eSIR_FALSE,
9035 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309036 if (eHAL_STATUS_SUCCESS == status)
9037 {
9038 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309039 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309040 &pAdapter->change_country_code,
9041 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309042 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309043 {
9044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309045 FL("SME Timed out while setting country code %ld"),
9046 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009047
9048 if (pHddCtx->isLogpInProgress)
9049 {
9050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9051 "%s: LOGP in Progress. Ignore!!!", __func__);
9052 return -EAGAIN;
9053 }
Kiet Lam10841362013-11-01 11:36:50 +05309054 }
9055 }
9056 else
9057 {
9058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009059 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309060 return -EINVAL;
9061 }
9062 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 status = hdd_init_ap_mode(pAdapter);
9064 if(status != VOS_STATUS_SUCCESS)
9065 {
9066 hddLog(VOS_TRACE_LEVEL_FATAL,
9067 "%s: Error initializing the ap mode", __func__);
9068 return -EINVAL;
9069 }
9070 hdd_set_conparam(1);
9071
Nirav Shah7e3c8132015-06-22 23:51:42 +05309072 status = hdd_sta_id_hash_attach(pAdapter);
9073 if (VOS_STATUS_SUCCESS != status)
9074 {
9075 hddLog(VOS_TRACE_LEVEL_ERROR,
9076 FL("Failed to initialize hash for AP"));
9077 return -EINVAL;
9078 }
9079
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 /*interface type changed update in wiphy structure*/
9081 if(wdev)
9082 {
9083 wdev->iftype = type;
9084 pHddCtx->change_iface = type;
9085 }
9086 else
9087 {
9088 hddLog(VOS_TRACE_LEVEL_ERROR,
9089 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9090 return -EINVAL;
9091 }
9092 goto done;
9093 }
9094
9095 default:
9096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9097 __func__);
9098 return -EOPNOTSUPP;
9099 }
9100 }
9101 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 )
9104 {
9105 switch(type)
9106 {
9107 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309110
9111 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309112#ifdef FEATURE_WLAN_TDLS
9113
9114 /* A Mutex Lock is introduced while changing the mode to
9115 * protect the concurrent access for the Adapters by TDLS
9116 * module.
9117 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309118 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309119#endif
c_hpothu002231a2015-02-05 14:58:51 +05309120 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009122 //Check for sub-string p2p to confirm its a p2p interface
9123 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009124 {
9125 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9126 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9127 }
9128 else
9129 {
9130 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 hdd_set_conparam(0);
9134 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9136 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309137#ifdef FEATURE_WLAN_TDLS
9138 mutex_unlock(&pHddCtx->tdls_lock);
9139#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309140 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 if( VOS_STATUS_SUCCESS != status )
9142 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009143 /* In case of JB, for P2P-GO, only change interface will be called,
9144 * This is the right place to enable back bmps_imps()
9145 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309146 if (pHddCtx->hdd_wlan_suspended)
9147 {
9148 hdd_set_pwrparams(pHddCtx);
9149 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009150 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 goto done;
9152 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9156 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 goto done;
9158 default:
9159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9160 __func__);
9161 return -EOPNOTSUPP;
9162
9163 }
9164
9165 }
9166 else
9167 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309168 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9169 __func__, hdd_device_modetoString(pAdapter->device_mode),
9170 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 return -EOPNOTSUPP;
9172 }
9173
9174
9175 if(pRoamProfile)
9176 {
9177 if ( LastBSSType != pRoamProfile->BSSType )
9178 {
9179 /*interface type changed update in wiphy structure*/
9180 wdev->iftype = type;
9181
9182 /*the BSS mode changed, We need to issue disconnect
9183 if connected or in IBSS disconnect state*/
9184 if ( hdd_connGetConnectedBssType(
9185 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9186 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9187 {
9188 /*need to issue a disconnect to CSR.*/
9189 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9190 if( eHAL_STATUS_SUCCESS ==
9191 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9192 pAdapter->sessionId,
9193 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9194 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309195 ret = wait_for_completion_interruptible_timeout(
9196 &pAdapter->disconnect_comp_var,
9197 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9198 if (ret <= 0)
9199 {
9200 hddLog(VOS_TRACE_LEVEL_ERROR,
9201 FL("wait on disconnect_comp_var failed %ld"), ret);
9202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 }
9204 }
9205 }
9206 }
9207
9208done:
9209 /*set bitmask based on updated value*/
9210 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009211
9212 /* Only STA mode support TM now
9213 * all other mode, TM feature should be disabled */
9214 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9215 (~VOS_STA & pHddCtx->concurrency_mode) )
9216 {
9217 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9218 }
9219
Jeff Johnson295189b2012-06-20 16:38:30 -07009220#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309221 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309222 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 {
9224 //we are ok to do AMP
9225 pHddCtx->isAmpAllowed = VOS_TRUE;
9226 }
9227#endif //WLAN_BTAMP_FEATURE
9228 EXIT();
9229 return 0;
9230}
9231
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309232/*
9233 * FUNCTION: wlan_hdd_cfg80211_change_iface
9234 * wrapper function to protect the actual implementation from SSR.
9235 */
9236int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9237 struct net_device *ndev,
9238 enum nl80211_iftype type,
9239 u32 *flags,
9240 struct vif_params *params
9241 )
9242{
9243 int ret;
9244
9245 vos_ssr_protect(__func__);
9246 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9247 vos_ssr_unprotect(__func__);
9248
9249 return ret;
9250}
9251
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009252#ifdef FEATURE_WLAN_TDLS
9253static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309254 struct net_device *dev,
9255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9256 const u8 *mac,
9257#else
9258 u8 *mac,
9259#endif
9260 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009261{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009262 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009263 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309264 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309265 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309266 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309267 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009268
9269 ENTER();
9270
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309271 if (!dev) {
9272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9273 return -EINVAL;
9274 }
9275
9276 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9277 if (!pAdapter) {
9278 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9279 return -EINVAL;
9280 }
9281
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309282 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009283 {
9284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9285 "Invalid arguments");
9286 return -EINVAL;
9287 }
Hoonki Lee27511902013-03-14 18:19:06 -07009288
9289 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9290 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9291 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009293 "%s: TDLS mode is disabled OR not enabled in FW."
9294 MAC_ADDRESS_STR " Request declined.",
9295 __func__, MAC_ADDR_ARRAY(mac));
9296 return -ENOTSUPP;
9297 }
9298
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009299 if (pHddCtx->isLogpInProgress)
9300 {
9301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9302 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309303 wlan_hdd_tdls_set_link_status(pAdapter,
9304 mac,
9305 eTDLS_LINK_IDLE,
9306 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009307 return -EBUSY;
9308 }
9309
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309310 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309311 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009312
9313 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009315 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9316 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309317 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009318 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009319 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309320 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009321
9322 /* in add station, we accept existing valid staId if there is */
9323 if ((0 == update) &&
9324 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9325 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009326 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009328 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009329 " link_status %d. staId %d. add station ignored.",
9330 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9331 return 0;
9332 }
9333 /* in change station, we accept only when staId is valid */
9334 if ((1 == update) &&
9335 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9336 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9337 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009339 "%s: " MAC_ADDRESS_STR
9340 " link status %d. staId %d. change station %s.",
9341 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9342 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9343 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009344 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009345
9346 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309347 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9350 "%s: " MAC_ADDRESS_STR
9351 " TDLS setup is ongoing. Request declined.",
9352 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009353 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009354 }
9355
9356 /* first to check if we reached to maximum supported TDLS peer.
9357 TODO: for now, return -EPERM looks working fine,
9358 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309359 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9360 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009361 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9363 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309364 " TDLS Max peer already connected. Request declined."
9365 " Num of peers (%d), Max allowed (%d).",
9366 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9367 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009368 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009369 }
9370 else
9371 {
9372 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309373 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009374 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009375 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9377 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9378 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009379 return -EPERM;
9380 }
9381 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009382 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309383 wlan_hdd_tdls_set_link_status(pAdapter,
9384 mac,
9385 eTDLS_LINK_CONNECTING,
9386 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009387
Jeff Johnsond75fe012013-04-06 10:53:06 -07009388 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309389 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009390 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009392 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009393 if(StaParams->htcap_present)
9394 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009396 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009398 "ht_capa->extended_capabilities: %0x",
9399 StaParams->HTCap.extendedHtCapInfo);
9400 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009402 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009404 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009405 if(StaParams->vhtcap_present)
9406 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009408 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9409 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9410 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9411 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009412 {
9413 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009415 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009417 "[%d]: %x ", i, StaParams->supported_rates[i]);
9418 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009419 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309420 else if ((1 == update) && (NULL == StaParams))
9421 {
9422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9423 "%s : update is true, but staParams is NULL. Error!", __func__);
9424 return -EPERM;
9425 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009426
9427 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9428
9429 if (!update)
9430 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309431 /*Before adding sta make sure that device exited from BMPS*/
9432 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9433 {
9434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9435 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9436 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9437 if (status != VOS_STATUS_SUCCESS) {
9438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9439 }
9440 }
9441
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309442 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009443 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309444 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309445 hddLog(VOS_TRACE_LEVEL_ERROR,
9446 FL("Failed to add TDLS peer STA. Enable Bmps"));
9447 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309448 return -EPERM;
9449 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009450 }
9451 else
9452 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309453 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009454 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309455 if (ret != eHAL_STATUS_SUCCESS) {
9456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9457 return -EPERM;
9458 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009459 }
9460
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309461 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009462 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9463
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309464 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009465 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 "%s: timeout waiting for tdls add station indication %ld",
9468 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009469 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009470 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309471
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009472 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9473 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009475 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009476 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009477 }
9478
9479 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009480
9481error:
Atul Mittal115287b2014-07-08 13:26:33 +05309482 wlan_hdd_tdls_set_link_status(pAdapter,
9483 mac,
9484 eTDLS_LINK_IDLE,
9485 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009486 return -EPERM;
9487
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009488}
9489#endif
9490
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309491static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309493#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9494 const u8 *mac,
9495#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009496 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309497#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 struct station_parameters *params)
9499{
9500 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309501 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309502 hdd_context_t *pHddCtx;
9503 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309505 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009506#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009507 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009508 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309509 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009510#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009511
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309512 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309513
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309514 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309515 if ((NULL == pAdapter))
9516 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309518 "invalid adapter ");
9519 return -EINVAL;
9520 }
9521
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309522 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9523 TRACE_CODE_HDD_CHANGE_STATION,
9524 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309526
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309527 ret = wlan_hdd_validate_context(pHddCtx);
9528 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309529 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309530 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309531 }
9532
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309533 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9534
9535 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009536 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9538 "invalid HDD station context");
9539 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9542
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009543 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9544 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009546 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309548 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 WLANTL_STA_AUTHENTICATED);
9550
Gopichand Nakkala29149562013-05-10 21:43:41 +05309551 if (status != VOS_STATUS_SUCCESS)
9552 {
9553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9554 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9555 return -EINVAL;
9556 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 }
9558 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009559 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9560 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309561#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009562 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9563 StaParams.capability = params->capability;
9564 StaParams.uapsd_queues = params->uapsd_queues;
9565 StaParams.max_sp = params->max_sp;
9566
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309567 /* Convert (first channel , number of channels) tuple to
9568 * the total list of channels. This goes with the assumption
9569 * that if the first channel is < 14, then the next channels
9570 * are an incremental of 1 else an incremental of 4 till the number
9571 * of channels.
9572 */
9573 if (0 != params->supported_channels_len) {
9574 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9575 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9576 {
9577 int wifi_chan_index;
9578 StaParams.supported_channels[j] = params->supported_channels[i];
9579 wifi_chan_index =
9580 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9581 no_of_channels = params->supported_channels[i+1];
9582 for(k=1; k <= no_of_channels; k++)
9583 {
9584 StaParams.supported_channels[j+1] =
9585 StaParams.supported_channels[j] + wifi_chan_index;
9586 j+=1;
9587 }
9588 }
9589 StaParams.supported_channels_len = j;
9590 }
9591 vos_mem_copy(StaParams.supported_oper_classes,
9592 params->supported_oper_classes,
9593 params->supported_oper_classes_len);
9594 StaParams.supported_oper_classes_len =
9595 params->supported_oper_classes_len;
9596
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009597 if (0 != params->ext_capab_len)
9598 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9599 sizeof(StaParams.extn_capability));
9600
9601 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009602 {
9603 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009604 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009605 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009606
9607 StaParams.supported_rates_len = params->supported_rates_len;
9608
9609 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9610 * The supported_rates array , for all the structures propogating till Add Sta
9611 * to the firmware has to be modified , if the supplicant (ieee80211) is
9612 * modified to send more rates.
9613 */
9614
9615 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9616 */
9617 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9618 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9619
9620 if (0 != StaParams.supported_rates_len) {
9621 int i = 0;
9622 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9623 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009625 "Supported Rates with Length %d", StaParams.supported_rates_len);
9626 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009628 "[%d]: %0x", i, StaParams.supported_rates[i]);
9629 }
9630
9631 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009632 {
9633 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009634 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009635 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009636
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009637 if (0 != params->ext_capab_len ) {
9638 /*Define A Macro : TODO Sunil*/
9639 if ((1<<4) & StaParams.extn_capability[3]) {
9640 isBufSta = 1;
9641 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309642 /* TDLS Channel Switching Support */
9643 if ((1<<6) & StaParams.extn_capability[3]) {
9644 isOffChannelSupported = 1;
9645 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009646 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309647 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9648 &StaParams, isBufSta,
9649 isOffChannelSupported);
9650
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309651 if (VOS_STATUS_SUCCESS != status) {
9652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9653 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9654 return -EINVAL;
9655 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009656 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9657
9658 if (VOS_STATUS_SUCCESS != status) {
9659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9660 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9661 return -EINVAL;
9662 }
9663 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009664#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309665 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009666 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 return status;
9668}
9669
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9671static int wlan_hdd_change_station(struct wiphy *wiphy,
9672 struct net_device *dev,
9673 const u8 *mac,
9674 struct station_parameters *params)
9675#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309676static int wlan_hdd_change_station(struct wiphy *wiphy,
9677 struct net_device *dev,
9678 u8 *mac,
9679 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309680#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309681{
9682 int ret;
9683
9684 vos_ssr_protect(__func__);
9685 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9686 vos_ssr_unprotect(__func__);
9687
9688 return ret;
9689}
9690
Jeff Johnson295189b2012-06-20 16:38:30 -07009691/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309692 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 * This function is used to initialize the key information
9694 */
9695#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309696static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 struct net_device *ndev,
9698 u8 key_index, bool pairwise,
9699 const u8 *mac_addr,
9700 struct key_params *params
9701 )
9702#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309703static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 struct net_device *ndev,
9705 u8 key_index, const u8 *mac_addr,
9706 struct key_params *params
9707 )
9708#endif
9709{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009710 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 tCsrRoamSetKey setKey;
9712 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309713 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009714 v_U32_t roamId= 0xFF;
9715 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 hdd_hostapd_state_t *pHostapdState;
9717 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009718 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309719 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009720
9721 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9724 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9725 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309726 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9727 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309728 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009729 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309730 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009731 }
9732
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9734 __func__, hdd_device_modetoString(pAdapter->device_mode),
9735 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009736
9737 if (CSR_MAX_NUM_KEY <= key_index)
9738 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 key_index);
9741
9742 return -EINVAL;
9743 }
9744
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009745 if (CSR_MAX_KEY_LEN < params->key_len)
9746 {
9747 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9748 params->key_len);
9749
9750 return -EINVAL;
9751 }
9752
9753 hddLog(VOS_TRACE_LEVEL_INFO,
9754 "%s: called with key index = %d & key length %d",
9755 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009756
9757 /*extract key idx, key len and key*/
9758 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9759 setKey.keyId = key_index;
9760 setKey.keyLength = params->key_len;
9761 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9762
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009763 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 {
9765 case WLAN_CIPHER_SUITE_WEP40:
9766 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9767 break;
9768
9769 case WLAN_CIPHER_SUITE_WEP104:
9770 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9771 break;
9772
9773 case WLAN_CIPHER_SUITE_TKIP:
9774 {
9775 u8 *pKey = &setKey.Key[0];
9776 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9777
9778 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9779
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009780 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009781
9782 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009783 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 |--------------|----------|----------|
9785 <---16bytes---><--8bytes--><--8bytes-->
9786
9787 */
9788 /*Sme expects the 32 bytes key to be in the below order
9789
9790 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009791 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 |--------------|----------|----------|
9793 <---16bytes---><--8bytes--><--8bytes-->
9794 */
9795 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009796 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009797
9798 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009799 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009800
9801 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009802 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009803
9804
9805 break;
9806 }
9807
9808 case WLAN_CIPHER_SUITE_CCMP:
9809 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9810 break;
9811
9812#ifdef FEATURE_WLAN_WAPI
9813 case WLAN_CIPHER_SUITE_SMS4:
9814 {
9815 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9816 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9817 params->key, params->key_len);
9818 return 0;
9819 }
9820#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009821
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009822#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 case WLAN_CIPHER_SUITE_KRK:
9824 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9825 break;
9826#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009827
9828#ifdef WLAN_FEATURE_11W
9829 case WLAN_CIPHER_SUITE_AES_CMAC:
9830 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009831 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009832#endif
9833
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309837 status = -EOPNOTSUPP;
9838 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009839 }
9840
9841 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9842 __func__, setKey.encType);
9843
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009844 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9846 (!pairwise)
9847#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009848 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009849#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009850 )
9851 {
9852 /* set group key*/
9853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9854 "%s- %d: setting Broadcast key",
9855 __func__, __LINE__);
9856 setKey.keyDirection = eSIR_RX_ONLY;
9857 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9858 }
9859 else
9860 {
9861 /* set pairwise key*/
9862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9863 "%s- %d: setting pairwise key",
9864 __func__, __LINE__);
9865 setKey.keyDirection = eSIR_TX_RX;
9866 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9867 }
9868 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9869 {
9870 setKey.keyDirection = eSIR_TX_RX;
9871 /*Set the group key*/
9872 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9873 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009874
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009875 if ( 0 != status )
9876 {
9877 hddLog(VOS_TRACE_LEVEL_ERROR,
9878 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309879 status = -EINVAL;
9880 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009881 }
9882 /*Save the keys here and call sme_RoamSetKey for setting
9883 the PTK after peer joins the IBSS network*/
9884 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9885 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309886 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009887 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309888 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9889 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9890 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009892 if( pHostapdState->bssState == BSS_START )
9893 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009894 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9895 vos_status = wlan_hdd_check_ula_done(pAdapter);
9896
9897 if ( vos_status != VOS_STATUS_SUCCESS )
9898 {
9899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9900 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9901 __LINE__, vos_status );
9902
9903 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9904
9905 status = -EINVAL;
9906 goto end;
9907 }
9908
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9910
9911 if ( status != eHAL_STATUS_SUCCESS )
9912 {
9913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9914 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9915 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309916 status = -EINVAL;
9917 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 }
9919 }
9920
9921 /* Saving WEP keys */
9922 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9923 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9924 {
9925 //Save the wep key in ap context. Issue setkey after the BSS is started.
9926 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9927 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9928 }
9929 else
9930 {
9931 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009932 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9934 }
9935 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009936 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9937 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 {
9939 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9940 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9941
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9943 if (!pairwise)
9944#else
9945 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9946#endif
9947 {
9948 /* set group key*/
9949 if (pHddStaCtx->roam_info.deferKeyComplete)
9950 {
9951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9952 "%s- %d: Perform Set key Complete",
9953 __func__, __LINE__);
9954 hdd_PerformRoamSetKeyComplete(pAdapter);
9955 }
9956 }
9957
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9959
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009960 pWextState->roamProfile.Keys.defaultIndex = key_index;
9961
9962
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009963 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 params->key, params->key_len);
9965
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 __func__, setKey.peerMac[0], setKey.peerMac[1],
9972 setKey.peerMac[2], setKey.peerMac[3],
9973 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 setKey.keyDirection);
9975
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009976 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309977
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009978 if ( vos_status != VOS_STATUS_SUCCESS )
9979 {
9980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9982 __LINE__, vos_status );
9983
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009984 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009985
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009986 status = -EINVAL;
9987 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009988
9989 }
9990
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009991#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309992 /* The supplicant may attempt to set the PTK once pre-authentication
9993 is done. Save the key in the UMAC and include it in the ADD BSS
9994 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009995 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309996 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009997 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309998 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9999 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010000 status = 0;
10001 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010002 }
10003 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
10004 {
10005 hddLog(VOS_TRACE_LEVEL_ERROR,
10006 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010007 status = -EINVAL;
10008 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010009 }
10010#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010011
10012 /* issue set key request to SME*/
10013 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10014 pAdapter->sessionId, &setKey, &roamId );
10015
10016 if ( 0 != status )
10017 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010018 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10020 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010021 status = -EINVAL;
10022 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 }
10024
10025
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010026 /* in case of IBSS as there was no information available about WEP keys during
10027 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010029 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10030 !( ( IW_AUTH_KEY_MGMT_802_1X
10031 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10033 )
10034 &&
10035 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10036 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10037 )
10038 )
10039 {
10040 setKey.keyDirection = eSIR_RX_ONLY;
10041 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10042
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 __func__, setKey.peerMac[0], setKey.peerMac[1],
10046 setKey.peerMac[2], setKey.peerMac[3],
10047 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 setKey.keyDirection);
10049
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010050 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 pAdapter->sessionId, &setKey, &roamId );
10052
10053 if ( 0 != status )
10054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010055 hddLog(VOS_TRACE_LEVEL_ERROR,
10056 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 __func__, status);
10058 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010059 status = -EINVAL;
10060 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 }
10062 }
10063 }
10064
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010065end:
10066 /* Need to clear any trace of key value in the memory.
10067 * Thus zero out the memory even though it is local
10068 * variable.
10069 */
10070 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010071 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010072 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010073}
10074
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10076static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10077 struct net_device *ndev,
10078 u8 key_index, bool pairwise,
10079 const u8 *mac_addr,
10080 struct key_params *params
10081 )
10082#else
10083static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10084 struct net_device *ndev,
10085 u8 key_index, const u8 *mac_addr,
10086 struct key_params *params
10087 )
10088#endif
10089{
10090 int ret;
10091 vos_ssr_protect(__func__);
10092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10093 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10094 mac_addr, params);
10095#else
10096 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10097 params);
10098#endif
10099 vos_ssr_unprotect(__func__);
10100
10101 return ret;
10102}
10103
Jeff Johnson295189b2012-06-20 16:38:30 -070010104/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010105 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 * This function is used to get the key information
10107 */
10108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010109static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010110 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010111 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 const u8 *mac_addr, void *cookie,
10114 void (*callback)(void *cookie, struct key_params*)
10115 )
10116#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010117static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010118 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 struct net_device *ndev,
10120 u8 key_index, const u8 *mac_addr, void *cookie,
10121 void (*callback)(void *cookie, struct key_params*)
10122 )
10123#endif
10124{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010125 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010126 hdd_wext_state_t *pWextState = NULL;
10127 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010129 hdd_context_t *pHddCtx;
10130 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010131
10132 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010133
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010134 if (NULL == pAdapter)
10135 {
10136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10137 "%s: HDD adapter is Null", __func__);
10138 return -ENODEV;
10139 }
10140
10141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10142 ret = wlan_hdd_validate_context(pHddCtx);
10143 if (0 != ret)
10144 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010145 return ret;
10146 }
10147
10148 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10149 pRoamProfile = &(pWextState->roamProfile);
10150
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10152 __func__, hdd_device_modetoString(pAdapter->device_mode),
10153 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010154
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 memset(&params, 0, sizeof(params));
10156
10157 if (CSR_MAX_NUM_KEY <= key_index)
10158 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010161 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010162
10163 switch(pRoamProfile->EncryptionType.encryptionType[0])
10164 {
10165 case eCSR_ENCRYPT_TYPE_NONE:
10166 params.cipher = IW_AUTH_CIPHER_NONE;
10167 break;
10168
10169 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10170 case eCSR_ENCRYPT_TYPE_WEP40:
10171 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10172 break;
10173
10174 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10175 case eCSR_ENCRYPT_TYPE_WEP104:
10176 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10177 break;
10178
10179 case eCSR_ENCRYPT_TYPE_TKIP:
10180 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10181 break;
10182
10183 case eCSR_ENCRYPT_TYPE_AES:
10184 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10185 break;
10186
10187 default:
10188 params.cipher = IW_AUTH_CIPHER_NONE;
10189 break;
10190 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010191
c_hpothuaaf19692014-05-17 17:01:48 +053010192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10193 TRACE_CODE_HDD_CFG80211_GET_KEY,
10194 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010195
Jeff Johnson295189b2012-06-20 16:38:30 -070010196 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10197 params.seq_len = 0;
10198 params.seq = NULL;
10199 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10200 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010201 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 return 0;
10203}
10204
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10206static int wlan_hdd_cfg80211_get_key(
10207 struct wiphy *wiphy,
10208 struct net_device *ndev,
10209 u8 key_index, bool pairwise,
10210 const u8 *mac_addr, void *cookie,
10211 void (*callback)(void *cookie, struct key_params*)
10212 )
10213#else
10214static int wlan_hdd_cfg80211_get_key(
10215 struct wiphy *wiphy,
10216 struct net_device *ndev,
10217 u8 key_index, const u8 *mac_addr, void *cookie,
10218 void (*callback)(void *cookie, struct key_params*)
10219 )
10220#endif
10221{
10222 int ret;
10223
10224 vos_ssr_protect(__func__);
10225#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10226 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10227 mac_addr, cookie, callback);
10228#else
10229 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10230 callback);
10231#endif
10232 vos_ssr_unprotect(__func__);
10233
10234 return ret;
10235}
10236
Jeff Johnson295189b2012-06-20 16:38:30 -070010237/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010238 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 * This function is used to delete the key information
10240 */
10241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010242static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010244 u8 key_index,
10245 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 const u8 *mac_addr
10247 )
10248#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010249static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 struct net_device *ndev,
10251 u8 key_index,
10252 const u8 *mac_addr
10253 )
10254#endif
10255{
10256 int status = 0;
10257
10258 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010259 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 //it is observed that this is invalidating peer
10261 //key index whenever re-key is done. This is affecting data link.
10262 //It should be ok to ignore del_key.
10263#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010264 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10265 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010266 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10267 tCsrRoamSetKey setKey;
10268 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 ENTER();
10271
10272 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10273 __func__,pAdapter->device_mode);
10274
10275 if (CSR_MAX_NUM_KEY <= key_index)
10276 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 key_index);
10279
10280 return -EINVAL;
10281 }
10282
10283 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10284 setKey.keyId = key_index;
10285
10286 if (mac_addr)
10287 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10288 else
10289 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10290
10291 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10292
10293 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 )
10296 {
10297
10298 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10300 if( pHostapdState->bssState == BSS_START)
10301 {
10302 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010303
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 if ( status != eHAL_STATUS_SUCCESS )
10305 {
10306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10307 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10308 __LINE__, status );
10309 }
10310 }
10311 }
10312 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010313 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 )
10315 {
10316 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10317
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010318 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10319
10320 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010322 __func__, setKey.peerMac[0], setKey.peerMac[1],
10323 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010325 if(pAdapter->sessionCtx.station.conn_info.connState ==
10326 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010328 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010330
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 if ( 0 != status )
10332 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010333 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 "%s: sme_RoamSetKey failure, returned %d",
10335 __func__, status);
10336 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10337 return -EINVAL;
10338 }
10339 }
10340 }
10341#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010342 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010343 return status;
10344}
10345
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10347static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10348 struct net_device *ndev,
10349 u8 key_index,
10350 bool pairwise,
10351 const u8 *mac_addr
10352 )
10353#else
10354static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10355 struct net_device *ndev,
10356 u8 key_index,
10357 const u8 *mac_addr
10358 )
10359#endif
10360{
10361 int ret;
10362
10363 vos_ssr_protect(__func__);
10364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10365 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10366 mac_addr);
10367#else
10368 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10369#endif
10370 vos_ssr_unprotect(__func__);
10371
10372 return ret;
10373}
10374
Jeff Johnson295189b2012-06-20 16:38:30 -070010375/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010376 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 * This function is used to set the default tx key index
10378 */
10379#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010380static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 struct net_device *ndev,
10382 u8 key_index,
10383 bool unicast, bool multicast)
10384#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010385static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 struct net_device *ndev,
10387 u8 key_index)
10388#endif
10389{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010390 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010391 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010392 hdd_wext_state_t *pWextState;
10393 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010394 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010395
10396 ENTER();
10397
Gopichand Nakkala29149562013-05-10 21:43:41 +053010398 if ((NULL == pAdapter))
10399 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010401 "invalid adapter");
10402 return -EINVAL;
10403 }
10404
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010405 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10406 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10407 pAdapter->sessionId, key_index));
10408
Gopichand Nakkala29149562013-05-10 21:43:41 +053010409 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10410 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10411
10412 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10413 {
10414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10415 "invalid Wext state or HDD context");
10416 return -EINVAL;
10417 }
10418
Arif Hussain6d2a3322013-11-17 19:50:10 -080010419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010421
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 if (CSR_MAX_NUM_KEY <= key_index)
10423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 key_index);
10426
10427 return -EINVAL;
10428 }
10429
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10431 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010432 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010433 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010434 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010435 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010439 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010441 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010442 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010443 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010444 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446 {
10447 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010449
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 tCsrRoamSetKey setKey;
10451 v_U32_t roamId= 0xFF;
10452 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010453
10454 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010455 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 Keys->defaultIndex = (u8)key_index;
10458 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10459 setKey.keyId = key_index;
10460 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010461
10462 vos_mem_copy(&setKey.Key[0],
10463 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010465
Gopichand Nakkala29149562013-05-10 21:43:41 +053010466 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010467
10468 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 &pHddStaCtx->conn_info.bssId[0],
10470 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010471
Gopichand Nakkala29149562013-05-10 21:43:41 +053010472 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10473 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10474 eCSR_ENCRYPT_TYPE_WEP104)
10475 {
10476 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10477 even though ap is configured for WEP-40 encryption. In this canse the key length
10478 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10479 type(104) and switching encryption type to 40*/
10480 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10481 eCSR_ENCRYPT_TYPE_WEP40;
10482 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10483 eCSR_ENCRYPT_TYPE_WEP40;
10484 }
10485
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010486 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010488
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010490 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 if ( 0 != status )
10494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010495 hddLog(VOS_TRACE_LEVEL_ERROR,
10496 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 status);
10498 return -EINVAL;
10499 }
10500 }
10501 }
10502
10503 /* In SoftAp mode setting key direction for default mode */
10504 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10505 {
10506 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10507 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10508 (eCSR_ENCRYPT_TYPE_AES !=
10509 pWextState->roamProfile.EncryptionType.encryptionType[0])
10510 )
10511 {
10512 /* Saving key direction for default key index to TX default */
10513 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10514 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10515 }
10516 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010517 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 return status;
10519}
10520
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10522static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10523 struct net_device *ndev,
10524 u8 key_index,
10525 bool unicast, bool multicast)
10526#else
10527static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10528 struct net_device *ndev,
10529 u8 key_index)
10530#endif
10531{
10532 int ret;
10533 vos_ssr_protect(__func__);
10534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10535 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10536 multicast);
10537#else
10538 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10539#endif
10540 vos_ssr_unprotect(__func__);
10541
10542 return ret;
10543}
10544
Jeff Johnson295189b2012-06-20 16:38:30 -070010545/*
10546 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10547 * This function is used to inform the BSS details to nl80211 interface.
10548 */
10549static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10550 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10551{
10552 struct net_device *dev = pAdapter->dev;
10553 struct wireless_dev *wdev = dev->ieee80211_ptr;
10554 struct wiphy *wiphy = wdev->wiphy;
10555 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10556 int chan_no;
10557 int ie_length;
10558 const char *ie;
10559 unsigned int freq;
10560 struct ieee80211_channel *chan;
10561 int rssi = 0;
10562 struct cfg80211_bss *bss = NULL;
10563
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 if( NULL == pBssDesc )
10565 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010566 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 return bss;
10568 }
10569
10570 chan_no = pBssDesc->channelId;
10571 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10572 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10573
10574 if( NULL == ie )
10575 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010576 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 return bss;
10578 }
10579
10580#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10581 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10582 {
10583 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10584 }
10585 else
10586 {
10587 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10588 }
10589#else
10590 freq = ieee80211_channel_to_frequency(chan_no);
10591#endif
10592
10593 chan = __ieee80211_get_channel(wiphy, freq);
10594
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010595 if (!chan) {
10596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10597 return NULL;
10598 }
10599
Abhishek Singhaee43942014-06-16 18:55:47 +053010600 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010601
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010602 return cfg80211_inform_bss(wiphy, chan,
10603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10604 CFG80211_BSS_FTYPE_UNKNOWN,
10605#endif
10606 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010607 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 pBssDesc->capabilityInfo,
10609 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010610 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010611}
10612
10613
10614
10615/*
10616 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10617 * This function is used to inform the BSS details to nl80211 interface.
10618 */
10619struct cfg80211_bss*
10620wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10621 tSirBssDescription *bss_desc
10622 )
10623{
10624 /*
10625 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10626 already exists in bss data base of cfg80211 for that particular BSS ID.
10627 Using cfg80211_inform_bss_frame to update the bss entry instead of
10628 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10629 now there is no possibility to get the mgmt(probe response) frame from PE,
10630 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10631 cfg80211_inform_bss_frame.
10632 */
10633 struct net_device *dev = pAdapter->dev;
10634 struct wireless_dev *wdev = dev->ieee80211_ptr;
10635 struct wiphy *wiphy = wdev->wiphy;
10636 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010637#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10638 qcom_ie_age *qie_age = NULL;
10639 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10640#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010641 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 const char *ie =
10644 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10645 unsigned int freq;
10646 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010647 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 struct cfg80211_bss *bss_status = NULL;
10649 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10650 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010651 hdd_context_t *pHddCtx;
10652 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010653#ifdef WLAN_OPEN_SOURCE
10654 struct timespec ts;
10655#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010657
Wilson Yangf80a0542013-10-07 13:02:37 -070010658 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10659 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010660 if (0 != status)
10661 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010662 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010663 }
10664
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010665 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010666 if (!mgmt)
10667 {
10668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10669 "%s: memory allocation failed ", __func__);
10670 return NULL;
10671 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010672
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010674
10675#ifdef WLAN_OPEN_SOURCE
10676 /* Android does not want the timestamp from the frame.
10677 Instead it wants a monotonic increasing value */
10678 get_monotonic_boottime(&ts);
10679 mgmt->u.probe_resp.timestamp =
10680 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10681#else
10682 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10684 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010685
10686#endif
10687
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10689 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010690
10691#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10692 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10693 /* Assuming this is the last IE, copy at the end */
10694 ie_length -=sizeof(qcom_ie_age);
10695 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10696 qie_age->element_id = QCOM_VENDOR_IE_ID;
10697 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10698 qie_age->oui_1 = QCOM_OUI1;
10699 qie_age->oui_2 = QCOM_OUI2;
10700 qie_age->oui_3 = QCOM_OUI3;
10701 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10702 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10703#endif
10704
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010706 if (bss_desc->fProbeRsp)
10707 {
10708 mgmt->frame_control |=
10709 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10710 }
10711 else
10712 {
10713 mgmt->frame_control |=
10714 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10715 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010716
10717#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010718 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10720 {
10721 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10722 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010723 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10725
10726 {
10727 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10728 }
10729 else
10730 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10732 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 kfree(mgmt);
10734 return NULL;
10735 }
10736#else
10737 freq = ieee80211_channel_to_frequency(chan_no);
10738#endif
10739 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010740 /*when the band is changed on the fly using the GUI, three things are done
10741 * 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)
10742 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10743 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10744 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10745 * and discards the channels correponding to previous band and calls back with zero bss results.
10746 * 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
10747 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10748 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10749 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10750 * So drop the bss and continue to next bss.
10751 */
10752 if(chan == NULL)
10753 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010755 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010756 return NULL;
10757 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010758 /*To keep the rssi icon of the connected AP in the scan window
10759 *and the rssi icon of the wireless networks in sync
10760 * */
10761 if (( eConnectionState_Associated ==
10762 pAdapter->sessionCtx.station.conn_info.connState ) &&
10763 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10764 pAdapter->sessionCtx.station.conn_info.bssId,
10765 WNI_CFG_BSSID_LEN)) &&
10766 (pHddCtx->hdd_wlan_suspended == FALSE))
10767 {
10768 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10769 rssi = (pAdapter->rssi * 100);
10770 }
10771 else
10772 {
10773 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10774 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010775
Nirav Shah20ac06f2013-12-12 18:14:06 +053010776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010777 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10778 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010779
Jeff Johnson295189b2012-06-20 16:38:30 -070010780 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10781 frame_len, rssi, GFP_KERNEL);
10782 kfree(mgmt);
10783 return bss_status;
10784}
10785
10786/*
10787 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10788 * This function is used to update the BSS data base of CFG8011
10789 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010790struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 tCsrRoamInfo *pRoamInfo
10792 )
10793{
10794 tCsrRoamConnectedProfile roamProfile;
10795 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10796 struct cfg80211_bss *bss = NULL;
10797
10798 ENTER();
10799
10800 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10801 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10802
10803 if (NULL != roamProfile.pBssDesc)
10804 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010805 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10806 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010807
10808 if (NULL == bss)
10809 {
10810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10811 __func__);
10812 }
10813
10814 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10815 }
10816 else
10817 {
10818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10819 __func__);
10820 }
10821 return bss;
10822}
10823
10824/*
10825 * FUNCTION: wlan_hdd_cfg80211_update_bss
10826 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010827static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10828 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010830{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010831 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 tCsrScanResultInfo *pScanResult;
10833 eHalStatus status = 0;
10834 tScanResultHandle pResult;
10835 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010836 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010837 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010838 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10841 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10842 NO_SESSION, pAdapter->sessionId));
10843
Wilson Yangf80a0542013-10-07 13:02:37 -070010844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10845
10846 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10849 "%s:LOGP in Progress. Ignore!!!",__func__);
10850 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 }
10852
Wilson Yangf80a0542013-10-07 13:02:37 -070010853
10854 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010855 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010856 {
10857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10858 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10859 return VOS_STATUS_E_PERM;
10860 }
10861
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010862 if (pAdapter->request != NULL)
10863 {
10864 if ((pAdapter->request->n_ssids == 1)
10865 && (pAdapter->request->ssids != NULL)
10866 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10867 is_p2p_scan = true;
10868 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 /*
10870 * start getting scan results and populate cgf80211 BSS database
10871 */
10872 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10873
10874 /* no scan results */
10875 if (NULL == pResult)
10876 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10878 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010879 wlan_hdd_get_frame_logs(pAdapter,
10880 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010881 return status;
10882 }
10883
10884 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10885
10886 while (pScanResult)
10887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010888 /*
10889 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10890 * entry already exists in bss data base of cfg80211 for that
10891 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10892 * bss entry instead of cfg80211_inform_bss, But this call expects
10893 * mgmt packet as input. As of now there is no possibility to get
10894 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 * ieee80211_mgmt(probe response) and passing to c
10896 * fg80211_inform_bss_frame.
10897 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010898 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10899 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10900 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010901 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10902 continue; //Skip the non p2p bss entries
10903 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10905 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010906
Jeff Johnson295189b2012-06-20 16:38:30 -070010907
10908 if (NULL == bss_status)
10909 {
10910 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010911 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 }
10913 else
10914 {
Yue Maf49ba872013-08-19 12:04:25 -070010915 cfg80211_put_bss(
10916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10917 wiphy,
10918#endif
10919 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 }
10921
10922 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10923 }
10924
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010925 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010926 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010928}
10929
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010930void
10931hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10932{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010933 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010934 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010935} /****** end hddPrintMacAddr() ******/
10936
10937void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010938hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010939{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010940 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010941 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010942 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10943 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10944 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010945} /****** end hddPrintPmkId() ******/
10946
10947//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10948//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10949
10950//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10951//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10952
10953#define dump_bssid(bssid) \
10954 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010955 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10956 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010957 }
10958
10959#define dump_pmkid(pMac, pmkid) \
10960 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010961 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10962 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010963 }
10964
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010965#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010966/*
10967 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10968 * This function is used to notify the supplicant of a new PMKSA candidate.
10969 */
10970int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010971 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010972 int index, bool preauth )
10973{
Jeff Johnsone7245742012-09-05 17:12:55 -070010974#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010975 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010976 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010977
10978 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010979 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010980
10981 if( NULL == pRoamInfo )
10982 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010983 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010984 return -EINVAL;
10985 }
10986
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010987 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10988 {
10989 dump_bssid(pRoamInfo->bssid);
10990 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010991 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010992 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010993#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010994 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010995}
10996#endif //FEATURE_WLAN_LFR
10997
Yue Maef608272013-04-08 23:09:17 -070010998#ifdef FEATURE_WLAN_LFR_METRICS
10999/*
11000 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
11001 * 802.11r/LFR metrics reporting function to report preauth initiation
11002 *
11003 */
11004#define MAX_LFR_METRICS_EVENT_LENGTH 100
11005VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
11006 tCsrRoamInfo *pRoamInfo)
11007{
11008 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11009 union iwreq_data wrqu;
11010
11011 ENTER();
11012
11013 if (NULL == pAdapter)
11014 {
11015 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11016 return VOS_STATUS_E_FAILURE;
11017 }
11018
11019 /* create the event */
11020 memset(&wrqu, 0, sizeof(wrqu));
11021 memset(metrics_notification, 0, sizeof(metrics_notification));
11022
11023 wrqu.data.pointer = metrics_notification;
11024 wrqu.data.length = scnprintf(metrics_notification,
11025 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11026 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11027
11028 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11029
11030 EXIT();
11031
11032 return VOS_STATUS_SUCCESS;
11033}
11034
11035/*
11036 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11037 * 802.11r/LFR metrics reporting function to report preauth completion
11038 * or failure
11039 */
11040VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11041 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11042{
11043 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11044 union iwreq_data wrqu;
11045
11046 ENTER();
11047
11048 if (NULL == pAdapter)
11049 {
11050 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11051 return VOS_STATUS_E_FAILURE;
11052 }
11053
11054 /* create the event */
11055 memset(&wrqu, 0, sizeof(wrqu));
11056 memset(metrics_notification, 0, sizeof(metrics_notification));
11057
11058 scnprintf(metrics_notification, sizeof(metrics_notification),
11059 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11060 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11061
11062 if (1 == preauth_status)
11063 strncat(metrics_notification, " TRUE", 5);
11064 else
11065 strncat(metrics_notification, " FALSE", 6);
11066
11067 wrqu.data.pointer = metrics_notification;
11068 wrqu.data.length = strlen(metrics_notification);
11069
11070 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11071
11072 EXIT();
11073
11074 return VOS_STATUS_SUCCESS;
11075}
11076
11077/*
11078 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11079 * 802.11r/LFR metrics reporting function to report handover initiation
11080 *
11081 */
11082VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11083 tCsrRoamInfo *pRoamInfo)
11084{
11085 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11086 union iwreq_data wrqu;
11087
11088 ENTER();
11089
11090 if (NULL == pAdapter)
11091 {
11092 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11093 return VOS_STATUS_E_FAILURE;
11094 }
11095
11096 /* create the event */
11097 memset(&wrqu, 0, sizeof(wrqu));
11098 memset(metrics_notification, 0, sizeof(metrics_notification));
11099
11100 wrqu.data.pointer = metrics_notification;
11101 wrqu.data.length = scnprintf(metrics_notification,
11102 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11103 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11104
11105 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11106
11107 EXIT();
11108
11109 return VOS_STATUS_SUCCESS;
11110}
11111#endif
11112
Jeff Johnson295189b2012-06-20 16:38:30 -070011113/*
11114 * FUNCTION: hdd_cfg80211_scan_done_callback
11115 * scanning callback function, called after finishing scan
11116 *
11117 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011118static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011119 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11120{
11121 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011122 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011124 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 struct cfg80211_scan_request *req = NULL;
11126 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011127 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011128 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011129 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011130 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011131
11132 ENTER();
11133
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011134 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011135 if (NULL == pHddCtx) {
11136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011137 goto allow_suspend;
11138 }
11139
11140 pScanInfo = &pHddCtx->scan_info;
11141
Jeff Johnson295189b2012-06-20 16:38:30 -070011142 hddLog(VOS_TRACE_LEVEL_INFO,
11143 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011144 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 __func__, halHandle, pContext, (int) scanId, (int) status);
11146
Kiet Lamac06e2c2013-10-23 16:25:07 +053011147 pScanInfo->mScanPendingCounter = 0;
11148
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011150 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 &pScanInfo->scan_req_completion_event,
11152 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011153 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011155 hddLog(VOS_TRACE_LEVEL_ERROR,
11156 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011158 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 }
11160
Yue Maef608272013-04-08 23:09:17 -070011161 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 {
11163 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011164 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 }
11166
11167 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011168 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 {
11170 hddLog(VOS_TRACE_LEVEL_INFO,
11171 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011172 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 (int) scanId);
11174 }
11175
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011176 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 pAdapter);
11178
11179 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011181
11182
11183 /* If any client wait scan result through WEXT
11184 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011185 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011186 {
11187 /* The other scan request waiting for current scan finish
11188 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011189 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011191 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 }
11193 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011194 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 {
11196 struct net_device *dev = pAdapter->dev;
11197 union iwreq_data wrqu;
11198 int we_event;
11199 char *msg;
11200
11201 memset(&wrqu, '\0', sizeof(wrqu));
11202 we_event = SIOCGIWSCAN;
11203 msg = NULL;
11204 wireless_send_event(dev, we_event, &wrqu, msg);
11205 }
11206 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011207 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011208
11209 /* Get the Scan Req */
11210 req = pAdapter->request;
11211
11212 if (!req)
11213 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011214 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011215 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011216 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011217 }
11218
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011220 /* Scan is no longer pending */
11221 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011222
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011223 /* last_scan_timestamp is used to decide if new scan
11224 * is needed or not on station interface. If last station
11225 * scan time and new station scan time is less then
11226 * last_scan_timestamp ; driver will return cached scan.
11227 */
11228 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11229 {
11230 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11231
11232 if ( req->n_channels )
11233 {
11234 for (i = 0; i < req->n_channels ; i++ )
11235 {
11236 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11237 }
11238 /* store no of channel scanned */
11239 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11240 }
11241
11242 }
11243
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011244 /*
11245 * cfg80211_scan_done informing NL80211 about completion
11246 * of scanning
11247 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011248 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11249 {
11250 aborted = true;
11251 }
11252 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011253 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011254
Siddharth Bhal76972212014-10-15 16:22:51 +053011255 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11256 /* Generate new random mac addr for next scan */
11257 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11258 hdd_processSpoofMacAddrRequest(pHddCtx);
11259 }
11260
Jeff Johnsone7245742012-09-05 17:12:55 -070011261allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011262 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011263 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011264
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011265 /* Acquire wakelock to handle the case where APP's tries to suspend
11266 * immediatly after the driver gets connect request(i.e after scan)
11267 * from supplicant, this result in app's is suspending and not able
11268 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011269 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011270
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011271#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011272 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011273#endif
11274
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 EXIT();
11276 return 0;
11277}
11278
11279/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011280 * FUNCTION: hdd_isConnectionInProgress
11281 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011282 *
11283 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011284v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011285{
11286 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11287 hdd_station_ctx_t *pHddStaCtx = NULL;
11288 hdd_adapter_t *pAdapter = NULL;
11289 VOS_STATUS status = 0;
11290 v_U8_t staId = 0;
11291 v_U8_t *staMac = NULL;
11292
c_hpothu9b781ba2013-12-30 20:57:45 +053011293 if (TRUE == pHddCtx->btCoexModeSet)
11294 {
11295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011296 FL("BTCoex Mode operation in progress"));
11297 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011298 }
11299
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011300 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11301
11302 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11303 {
11304 pAdapter = pAdapterNode->pAdapter;
11305
11306 if( pAdapter )
11307 {
11308 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011309 "%s: Adapter with device mode %s (%d) exists",
11310 __func__, hdd_device_modetoString(pAdapter->device_mode),
11311 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011312 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011313 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11314 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11315 (eConnectionState_Connecting ==
11316 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11317 {
11318 hddLog(VOS_TRACE_LEVEL_ERROR,
11319 "%s: %p(%d) Connection is in progress", __func__,
11320 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11321 return VOS_TRUE;
11322 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011323 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011324 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011325 {
11326 hddLog(VOS_TRACE_LEVEL_ERROR,
11327 "%s: %p(%d) Reassociation is in progress", __func__,
11328 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11329 return VOS_TRUE;
11330 }
11331 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011332 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11333 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011334 {
11335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11336 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011337 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011338 {
11339 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11340 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011341 "%s: client " MAC_ADDRESS_STR
11342 " is in the middle of WPS/EAPOL exchange.", __func__,
11343 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011344 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011345 }
11346 }
11347 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11348 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11349 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011350 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11351 ptSapContext pSapCtx = NULL;
11352 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11353 if(pSapCtx == NULL){
11354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11355 FL("psapCtx is NULL"));
11356 return VOS_FALSE;
11357 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011358 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11359 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011360 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11361 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011362 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011363 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011364
11365 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011366 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11367 "middle of WPS/EAPOL exchange.", __func__,
11368 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011369 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011370 }
11371 }
11372 }
11373 }
11374 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11375 pAdapterNode = pNext;
11376 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011377 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011378}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011379
11380/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011381 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 * this scan respond to scan trigger and update cfg80211 scan database
11383 * later, scan dump command can be used to recieve scan results
11384 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011385int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011386#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11387 struct net_device *dev,
11388#endif
11389 struct cfg80211_scan_request *request)
11390{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011391 hdd_adapter_t *pAdapter = NULL;
11392 hdd_context_t *pHddCtx = NULL;
11393 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011394 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011395 tCsrScanRequest scanRequest;
11396 tANI_U8 *channelList = NULL, i;
11397 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011398 int status;
11399 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011401 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011402 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011403 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011404 v_S7_t rssi=0;
11405 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11408 struct net_device *dev = NULL;
11409 if (NULL == request)
11410 {
11411 hddLog(VOS_TRACE_LEVEL_ERROR,
11412 "%s: scan req param null", __func__);
11413 return -EINVAL;
11414 }
11415 dev = request->wdev->netdev;
11416#endif
11417
11418 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11419 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11420 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11421
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 ENTER();
11423
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11425 __func__, hdd_device_modetoString(pAdapter->device_mode),
11426 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011427
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011428 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011429 if (0 != status)
11430 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011431 return status;
11432 }
11433
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011434 if (NULL == pwextBuf)
11435 {
11436 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11437 __func__);
11438 return -EIO;
11439 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011440 cfg_param = pHddCtx->cfg_ini;
11441 pScanInfo = &pHddCtx->scan_info;
11442
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011443 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11444 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11445 {
11446 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11447 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11448 }
11449
Jeff Johnson295189b2012-06-20 16:38:30 -070011450#ifdef WLAN_BTAMP_FEATURE
11451 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011452 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011454 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 "%s: No scanning when AMP is on", __func__);
11456 return -EOPNOTSUPP;
11457 }
11458#endif
11459 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011460 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011462 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011463 "%s: Not scanning on device_mode = %s (%d)",
11464 __func__, hdd_device_modetoString(pAdapter->device_mode),
11465 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 return -EOPNOTSUPP;
11467 }
11468
11469 if (TRUE == pScanInfo->mScanPending)
11470 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011471 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11472 {
11473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11474 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011475 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 }
11477
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011478 // Don't allow scan if PNO scan is going on.
11479 if (pHddCtx->isPnoEnable)
11480 {
11481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11482 FL("pno scan in progress"));
11483 return -EBUSY;
11484 }
11485
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011486 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011487 //Channel and action frame is pending
11488 //Otherwise Cancel Remain On Channel and allow Scan
11489 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011490 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011491 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011493 return -EBUSY;
11494 }
11495
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11497 {
11498 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011499 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11503 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011504 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011505 "%s: MAX TM Level Scan not allowed", __func__);
11506 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011507 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 }
11509 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11510
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011511 /* Check if scan is allowed at this point of time.
11512 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011513 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011514 {
11515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11516 return -EBUSY;
11517 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011518
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11520
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011521 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11522 * Becasue of this, driver is assuming that this is not wildcard scan and so
11523 * is not aging out the scan results.
11524 */
11525 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011527 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011529
11530 if ((request->ssids) && (0 < request->n_ssids))
11531 {
11532 tCsrSSIDInfo *SsidInfo;
11533 int j;
11534 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11535 /* Allocate num_ssid tCsrSSIDInfo structure */
11536 SsidInfo = scanRequest.SSIDs.SSIDList =
11537 ( tCsrSSIDInfo *)vos_mem_malloc(
11538 request->n_ssids*sizeof(tCsrSSIDInfo));
11539
11540 if(NULL == scanRequest.SSIDs.SSIDList)
11541 {
11542 hddLog(VOS_TRACE_LEVEL_ERROR,
11543 "%s: memory alloc failed SSIDInfo buffer", __func__);
11544 return -ENOMEM;
11545 }
11546
11547 /* copy all the ssid's and their length */
11548 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11549 {
11550 /* get the ssid length */
11551 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11552 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11553 SsidInfo->SSID.length);
11554 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11555 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11556 j, SsidInfo->SSID.ssId);
11557 }
11558 /* set the scan type to active */
11559 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11560 }
11561 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11564 TRACE_CODE_HDD_CFG80211_SCAN,
11565 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 /* set the scan type to active */
11567 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011569 else
11570 {
11571 /*Set the scan type to default type, in this case it is ACTIVE*/
11572 scanRequest.scanType = pScanInfo->scan_mode;
11573 }
11574 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11575 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011576
11577 /* set BSSType to default type */
11578 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11579
11580 /*TODO: scan the requested channels only*/
11581
11582 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011583 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011585 hddLog(VOS_TRACE_LEVEL_WARN,
11586 "No of Scan Channels exceeded limit: %d", request->n_channels);
11587 request->n_channels = MAX_CHANNEL;
11588 }
11589
11590 hddLog(VOS_TRACE_LEVEL_INFO,
11591 "No of Scan Channels: %d", request->n_channels);
11592
11593
11594 if( request->n_channels )
11595 {
11596 char chList [(request->n_channels*5)+1];
11597 int len;
11598 channelList = vos_mem_malloc( request->n_channels );
11599 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011600 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011601 hddLog(VOS_TRACE_LEVEL_ERROR,
11602 "%s: memory alloc failed channelList", __func__);
11603 status = -ENOMEM;
11604 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011605 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011606
11607 for( i = 0, len = 0; i < request->n_channels ; i++ )
11608 {
11609 channelList[i] = request->channels[i]->hw_value;
11610 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11611 }
11612
Nirav Shah20ac06f2013-12-12 18:14:06 +053011613 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011614 "Channel-List: %s ", chList);
11615 }
c_hpothu53512302014-04-15 18:49:53 +053011616
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011617 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11618 scanRequest.ChannelInfo.ChannelList = channelList;
11619
11620 /* set requestType to full scan */
11621 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11622
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011623 /* if there is back to back scan happening in driver with in
11624 * nDeferScanTimeInterval interval driver should defer new scan request
11625 * and should provide last cached scan results instead of new channel list.
11626 * This rule is not applicable if scan is p2p scan.
11627 * This condition will work only in case when last request no of channels
11628 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011629 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011630 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011631 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011632
Sushant Kaushik86592172015-04-27 16:35:03 +053011633 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11634 /* if wps ie is NULL , then only defer scan */
11635 if ( pWpsIe == NULL &&
11636 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011637 {
11638 if ( pScanInfo->last_scan_timestamp !=0 &&
11639 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11640 {
11641 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11642 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11643 vos_mem_compare(pScanInfo->last_scan_channelList,
11644 channelList, pScanInfo->last_scan_numChannels))
11645 {
11646 hddLog(VOS_TRACE_LEVEL_WARN,
11647 " New and old station scan time differ is less then %u",
11648 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11649
11650 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011651 pAdapter);
11652
Agarwal Ashish57e84372014-12-05 18:26:53 +053011653 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011654 "Return old cached scan as all channels and no of channels are same");
11655
Agarwal Ashish57e84372014-12-05 18:26:53 +053011656 if (0 > ret)
11657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011658
Agarwal Ashish57e84372014-12-05 18:26:53 +053011659 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011660
11661 status = eHAL_STATUS_SUCCESS;
11662 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011663 }
11664 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011665 }
11666
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011667 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11668 * search (Flush on both full scan and social scan but not on single
11669 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11670 */
11671
11672 /* Supplicant does single channel scan after 8-way handshake
11673 * and in that case driver shoudnt flush scan results. If
11674 * driver flushes the scan results here and unfortunately if
11675 * the AP doesnt respond to our probe req then association
11676 * fails which is not desired
11677 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011678 if ((request->n_ssids == 1)
11679 && (request->ssids != NULL)
11680 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11681 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011682
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011683 if( is_p2p_scan ||
11684 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011685 {
11686 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11687 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11688 pAdapter->sessionId );
11689 }
11690
11691 if( request->ie_len )
11692 {
11693 /* save this for future association (join requires this) */
11694 /*TODO: Array needs to be converted to dynamic allocation,
11695 * as multiple ie.s can be sent in cfg80211_scan_request structure
11696 * CR 597966
11697 */
11698 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11699 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11700 pScanInfo->scanAddIE.length = request->ie_len;
11701
11702 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11703 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11704 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011706 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011708 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11709 memcpy( pwextBuf->roamProfile.addIEScan,
11710 request->ie, request->ie_len);
11711 }
11712 else
11713 {
11714 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11715 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 }
11717
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011718 }
11719 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11720 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11721
11722 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11723 request->ie_len);
11724 if (pP2pIe != NULL)
11725 {
11726#ifdef WLAN_FEATURE_P2P_DEBUG
11727 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11728 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11729 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011730 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011731 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11732 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11733 "Go nego completed to Connection is started");
11734 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11735 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011736 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011737 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11738 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011740 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11741 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11742 "Disconnected state to Connection is started");
11743 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11744 "for 4way Handshake");
11745 }
11746#endif
11747
11748 /* no_cck will be set during p2p find to disable 11b rates */
11749 if(TRUE == request->no_cck)
11750 {
11751 hddLog(VOS_TRACE_LEVEL_INFO,
11752 "%s: This is a P2P Search", __func__);
11753 scanRequest.p2pSearch = 1;
11754
11755 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011756 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011757 /* set requestType to P2P Discovery */
11758 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11759 }
11760
11761 /*
11762 Skip Dfs Channel in case of P2P Search
11763 if it is set in ini file
11764 */
11765 if(cfg_param->skipDfsChnlInP2pSearch)
11766 {
11767 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011768 }
11769 else
11770 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011771 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011772 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011773
Agarwal Ashish4f616132013-12-30 23:32:50 +053011774 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 }
11776 }
11777
11778 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11779
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011780#ifdef FEATURE_WLAN_TDLS
11781 /* if tdls disagree scan right now, return immediately.
11782 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11783 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11784 */
11785 status = wlan_hdd_tdls_scan_callback (pAdapter,
11786 wiphy,
11787#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11788 dev,
11789#endif
11790 request);
11791 if(status <= 0)
11792 {
11793 if(!status)
11794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11795 "scan rejected %d", __func__, status);
11796 else
11797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11798 __func__, status);
11799
11800 return status;
11801 }
11802#endif
11803
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011804 /* acquire the wakelock to avoid the apps suspend during the scan. To
11805 * address the following issues.
11806 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11807 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11808 * for long time, this result in apps running at full power for long time.
11809 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11810 * be stuck in full power because of resume BMPS
11811 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011812 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011813
Nirav Shah20ac06f2013-12-12 18:14:06 +053011814 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11815 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011816 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11817 scanRequest.requestType, scanRequest.scanType,
11818 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011819 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11820
Siddharth Bhal76972212014-10-15 16:22:51 +053011821 if (pHddCtx->spoofMacAddr.isEnabled)
11822 {
11823 hddLog(VOS_TRACE_LEVEL_INFO,
11824 "%s: MAC Spoofing enabled for current scan", __func__);
11825 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11826 * to fill TxBds for probe request during current scan
11827 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011828 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011829 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011830
11831 if(status != VOS_STATUS_SUCCESS)
11832 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011833 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011834 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011835#ifdef FEATURE_WLAN_TDLS
11836 wlan_hdd_tdls_scan_done_callback(pAdapter);
11837#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011838 goto free_mem;
11839 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011840 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011841 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011842 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011843 pAdapter->sessionId, &scanRequest, &scanId,
11844 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011845
Jeff Johnson295189b2012-06-20 16:38:30 -070011846 if (eHAL_STATUS_SUCCESS != status)
11847 {
11848 hddLog(VOS_TRACE_LEVEL_ERROR,
11849 "%s: sme_ScanRequest returned error %d", __func__, status);
11850 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011851 if(eHAL_STATUS_RESOURCES == status)
11852 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11854 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011855 status = -EBUSY;
11856 } else {
11857 status = -EIO;
11858 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011859 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011860
11861#ifdef FEATURE_WLAN_TDLS
11862 wlan_hdd_tdls_scan_done_callback(pAdapter);
11863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 goto free_mem;
11865 }
11866
11867 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011868 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 pAdapter->request = request;
11870 pScanInfo->scanId = scanId;
11871
11872 complete(&pScanInfo->scan_req_completion_event);
11873
11874free_mem:
11875 if( scanRequest.SSIDs.SSIDList )
11876 {
11877 vos_mem_free(scanRequest.SSIDs.SSIDList);
11878 }
11879
11880 if( channelList )
11881 vos_mem_free( channelList );
11882
11883 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011884 return status;
11885}
11886
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011887int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11888#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11889 struct net_device *dev,
11890#endif
11891 struct cfg80211_scan_request *request)
11892{
11893 int ret;
11894
11895 vos_ssr_protect(__func__);
11896 ret = __wlan_hdd_cfg80211_scan(wiphy,
11897#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11898 dev,
11899#endif
11900 request);
11901 vos_ssr_unprotect(__func__);
11902
11903 return ret;
11904}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011905
11906void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11907{
11908 v_U8_t iniDot11Mode =
11909 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11910 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11911
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011912 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11913 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011914 switch ( iniDot11Mode )
11915 {
11916 case eHDD_DOT11_MODE_AUTO:
11917 case eHDD_DOT11_MODE_11ac:
11918 case eHDD_DOT11_MODE_11ac_ONLY:
11919#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011920 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11921 sme_IsFeatureSupportedByFW(DOT11AC) )
11922 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11923 else
11924 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011925#else
11926 hddDot11Mode = eHDD_DOT11_MODE_11n;
11927#endif
11928 break;
11929 case eHDD_DOT11_MODE_11n:
11930 case eHDD_DOT11_MODE_11n_ONLY:
11931 hddDot11Mode = eHDD_DOT11_MODE_11n;
11932 break;
11933 default:
11934 hddDot11Mode = iniDot11Mode;
11935 break;
11936 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011937#ifdef WLAN_FEATURE_AP_HT40_24G
11938 if (operationChannel > SIR_11B_CHANNEL_END)
11939#endif
11940 {
11941 /* This call decides required channel bonding mode */
11942 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011943 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11944 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011945 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011946}
11947
Jeff Johnson295189b2012-06-20 16:38:30 -070011948/*
11949 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011950 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011952int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011953 const u8 *ssid, size_t ssid_len, const u8 *bssid,
11954 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011955{
11956 int status = 0;
11957 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011958 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 v_U32_t roamId;
11960 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011962 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011963
11964 ENTER();
11965
11966 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011967 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11968
11969 status = wlan_hdd_validate_context(pHddCtx);
11970 if (status)
11971 {
Yue Mae36e3552014-03-05 17:06:20 -080011972 return status;
11973 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11976 {
11977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11978 return -EINVAL;
11979 }
11980
11981 pRoamProfile = &pWextState->roamProfile;
11982
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011985 hdd_station_ctx_t *pHddStaCtx;
11986 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011987
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011988 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11989
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011990 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11992 {
11993 /*QoS not enabled in cfg file*/
11994 pRoamProfile->uapsd_mask = 0;
11995 }
11996 else
11997 {
11998 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
12001 }
12002
12003 pRoamProfile->SSIDs.numOfSSIDs = 1;
12004 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
12005 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012006 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
12008 ssid, ssid_len);
12009
12010 if (bssid)
12011 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012012 pValidBssid = bssid;
12013 }
12014 else if (bssid_hint)
12015 {
12016 pValidBssid = bssid_hint;
12017 }
12018 if (pValidBssid)
12019 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012021 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012023 /* Save BSSID in seperate variable as well, as RoamProfile
12024 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 case of join failure we should send valid BSSID to supplicant
12026 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012027 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 WNI_CFG_BSSID_LEN);
12029 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012030 else
12031 {
12032 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012034
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012035 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12036 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012037 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12038 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012039 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 /*set gen ie*/
12041 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12042 /*set auth*/
12043 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012045#ifdef FEATURE_WLAN_WAPI
12046 if (pAdapter->wapi_info.nWapiMode)
12047 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012048 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 switch (pAdapter->wapi_info.wapiAuthMode)
12050 {
12051 case WAPI_AUTH_MODE_PSK:
12052 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012053 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012054 pAdapter->wapi_info.wapiAuthMode);
12055 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12056 break;
12057 }
12058 case WAPI_AUTH_MODE_CERT:
12059 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012060 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 pAdapter->wapi_info.wapiAuthMode);
12062 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12063 break;
12064 }
12065 } // End of switch
12066 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12067 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12068 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012069 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 pRoamProfile->AuthType.numEntries = 1;
12071 pRoamProfile->EncryptionType.numEntries = 1;
12072 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12073 pRoamProfile->mcEncryptionType.numEntries = 1;
12074 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12075 }
12076 }
12077#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012078#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012079 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012080 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12081 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12082 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012083 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12084 sizeof (tSirGtkOffloadParams));
12085 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012086 }
12087#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 pRoamProfile->csrPersona = pAdapter->device_mode;
12089
Jeff Johnson32d95a32012-09-10 13:15:23 -070012090 if( operatingChannel )
12091 {
12092 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12093 pRoamProfile->ChannelInfo.numOfChannels = 1;
12094 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012095 else
12096 {
12097 pRoamProfile->ChannelInfo.ChannelList = NULL;
12098 pRoamProfile->ChannelInfo.numOfChannels = 0;
12099 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012100 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12101 {
12102 hdd_select_cbmode(pAdapter,operatingChannel);
12103 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012104
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012105 /*
12106 * Change conn_state to connecting before sme_RoamConnect(),
12107 * because sme_RoamConnect() has a direct path to call
12108 * hdd_smeRoamCallback(), which will change the conn_state
12109 * If direct path, conn_state will be accordingly changed
12110 * to NotConnected or Associated by either
12111 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12112 * in sme_RoamCallback()
12113 * if sme_RomConnect is to be queued,
12114 * Connecting state will remain until it is completed.
12115 * If connection state is not changed,
12116 * connection state will remain in eConnectionState_NotConnected state.
12117 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12118 * if conn state is eConnectionState_NotConnected.
12119 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12120 * informed of connect result indication which is an issue.
12121 */
12122
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012123 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12124 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012125 {
12126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012127 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012128 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12129 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012130 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012131 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012132 pAdapter->sessionId, pRoamProfile, &roamId);
12133
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012134 if ((eHAL_STATUS_SUCCESS != status) &&
12135 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12136 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012137
12138 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012139 hddLog(VOS_TRACE_LEVEL_ERROR,
12140 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12141 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012142 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012143 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012144 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012145 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012146
12147 pRoamProfile->ChannelInfo.ChannelList = NULL;
12148 pRoamProfile->ChannelInfo.numOfChannels = 0;
12149
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 }
12151 else
12152 {
12153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12154 return -EINVAL;
12155 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012156 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 return status;
12158}
12159
12160/*
12161 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12162 * This function is used to set the authentication type (OPEN/SHARED).
12163 *
12164 */
12165static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12166 enum nl80211_auth_type auth_type)
12167{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12170
12171 ENTER();
12172
12173 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012177 hddLog(VOS_TRACE_LEVEL_INFO,
12178 "%s: set authentication type to AUTOSWITCH", __func__);
12179 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12180 break;
12181
12182 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012183#ifdef WLAN_FEATURE_VOWIFI_11R
12184 case NL80211_AUTHTYPE_FT:
12185#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 "%s: set authentication type to OPEN", __func__);
12188 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12189 break;
12190
12191 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 "%s: set authentication type to SHARED", __func__);
12194 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12195 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012198 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 "%s: set authentication type to CCKM WPA", __func__);
12200 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12201 break;
12202#endif
12203
12204
12205 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012206 hddLog(VOS_TRACE_LEVEL_ERROR,
12207 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 auth_type);
12209 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12210 return -EINVAL;
12211 }
12212
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 pHddStaCtx->conn_info.authType;
12215 return 0;
12216}
12217
12218/*
12219 * FUNCTION: wlan_hdd_set_akm_suite
12220 * This function is used to set the key mgmt type(PSK/8021x).
12221 *
12222 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 u32 key_mgmt
12225 )
12226{
12227 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12228 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012229 /* Should be in ieee802_11_defs.h */
12230#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12231#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012232 /*set key mgmt type*/
12233 switch(key_mgmt)
12234 {
12235 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012236 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012237#ifdef WLAN_FEATURE_VOWIFI_11R
12238 case WLAN_AKM_SUITE_FT_PSK:
12239#endif
12240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 __func__);
12242 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12243 break;
12244
12245 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012246 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012247#ifdef WLAN_FEATURE_VOWIFI_11R
12248 case WLAN_AKM_SUITE_FT_8021X:
12249#endif
12250 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 __func__);
12252 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12253 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012254#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012255#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12256#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12257 case WLAN_AKM_SUITE_CCKM:
12258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12259 __func__);
12260 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12261 break;
12262#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012263#ifndef WLAN_AKM_SUITE_OSEN
12264#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12265 case WLAN_AKM_SUITE_OSEN:
12266 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12267 __func__);
12268 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12269 break;
12270#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012271
12272 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012274 __func__, key_mgmt);
12275 return -EINVAL;
12276
12277 }
12278 return 0;
12279}
12280
12281/*
12282 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012283 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 * (NONE/WEP40/WEP104/TKIP/CCMP).
12285 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012286static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12287 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 bool ucast
12289 )
12290{
12291 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012292 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12294
12295 ENTER();
12296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012297 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 __func__, cipher);
12301 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12302 }
12303 else
12304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012305
Jeff Johnson295189b2012-06-20 16:38:30 -070012306 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012307 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 {
12309 case IW_AUTH_CIPHER_NONE:
12310 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12311 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012312
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012314 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012318 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 case WLAN_CIPHER_SUITE_TKIP:
12322 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12323 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012324
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 case WLAN_CIPHER_SUITE_CCMP:
12326 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12327 break;
12328#ifdef FEATURE_WLAN_WAPI
12329 case WLAN_CIPHER_SUITE_SMS4:
12330 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12331 break;
12332#endif
12333
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012334#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 case WLAN_CIPHER_SUITE_KRK:
12336 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12337 break;
12338#endif
12339 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012341 __func__, cipher);
12342 return -EOPNOTSUPP;
12343 }
12344 }
12345
12346 if (ucast)
12347 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012348 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 __func__, encryptionType);
12350 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12351 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012352 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012353 encryptionType;
12354 }
12355 else
12356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012357 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 __func__, encryptionType);
12359 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12360 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12361 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12362 }
12363
12364 return 0;
12365}
12366
12367
12368/*
12369 * FUNCTION: wlan_hdd_cfg80211_set_ie
12370 * This function is used to parse WPA/RSN IE's.
12371 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012373#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12374 const u8 *ie,
12375#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012376 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 size_t ie_len
12379 )
12380{
12381 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012382#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12383 const u8 *genie = ie;
12384#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012386#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 v_U16_t remLen = ie_len;
12388#ifdef FEATURE_WLAN_WAPI
12389 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12390 u16 *tmp;
12391 v_U16_t akmsuiteCount;
12392 int *akmlist;
12393#endif
12394 ENTER();
12395
12396 /* clear previous assocAddIE */
12397 pWextState->assocAddIE.length = 0;
12398 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012399 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012400
12401 while (remLen >= 2)
12402 {
12403 v_U16_t eLen = 0;
12404 v_U8_t elementId;
12405 elementId = *genie++;
12406 eLen = *genie++;
12407 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012408
Arif Hussain6d2a3322013-11-17 19:50:10 -080012409 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012410 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012411
12412 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012414 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012415 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 -070012416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 "%s: Invalid WPA IE", __func__);
12419 return -EINVAL;
12420 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012421 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 {
12423 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012424 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012426
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012427 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012429 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12430 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 VOS_ASSERT(0);
12432 return -ENOMEM;
12433 }
12434 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12435 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12436 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012437
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12439 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12440 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12441 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012442 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12443 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12445 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12446 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12447 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12448 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12449 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012450 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012451 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 {
12453 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012454 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012456
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012457 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012459 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12460 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012461 VOS_ASSERT(0);
12462 return -ENOMEM;
12463 }
12464 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12465 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12466 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12469 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012471#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12473 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 /*Consider WFD IE, only for P2P Client */
12475 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12476 {
12477 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012478 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012481 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012482 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012483 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12484 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012485 VOS_ASSERT(0);
12486 return -ENOMEM;
12487 }
12488 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12489 // WPS IE + P2P IE + WFD IE
12490 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12491 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012492
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12494 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12495 }
12496#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012497 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012498 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012499 HS20_OUI_TYPE_SIZE)) )
12500 {
12501 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012502 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012503 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012504
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012505 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012506 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012507 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12508 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012509 VOS_ASSERT(0);
12510 return -ENOMEM;
12511 }
12512 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12513 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012514
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012515 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12516 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12517 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012518 /* Appending OSEN Information Element in Assiciation Request */
12519 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12520 OSEN_OUI_TYPE_SIZE)) )
12521 {
12522 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12523 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12524 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012525
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012526 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012527 {
12528 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12529 "Need bigger buffer space");
12530 VOS_ASSERT(0);
12531 return -ENOMEM;
12532 }
12533 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12534 pWextState->assocAddIE.length += eLen + 2;
12535
12536 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12537 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12538 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12539 }
12540
Abhishek Singh4322e622015-06-10 15:42:54 +053012541 /* Update only for WPA IE */
12542 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12543 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012544
12545 /* populating as ADDIE in beacon frames */
12546 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012547 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012548 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12549 {
12550 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12551 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12552 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12553 {
12554 hddLog(LOGE,
12555 "Coldn't pass "
12556 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12557 }
12558 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12559 else
12560 hddLog(LOGE,
12561 "Could not pass on "
12562 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12563
12564 /* IBSS mode doesn't contain params->proberesp_ies still
12565 beaconIE's need to be populated in probe response frames */
12566 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12567 {
12568 u16 rem_probe_resp_ie_len = eLen + 2;
12569 u8 probe_rsp_ie_len[3] = {0};
12570 u8 counter = 0;
12571
12572 /* Check Probe Resp Length if it is greater then 255 then
12573 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12574 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12575 not able Store More then 255 bytes into One Variable */
12576
12577 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12578 {
12579 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12580 {
12581 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12582 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12583 }
12584 else
12585 {
12586 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12587 rem_probe_resp_ie_len = 0;
12588 }
12589 }
12590
12591 rem_probe_resp_ie_len = 0;
12592
12593 if (probe_rsp_ie_len[0] > 0)
12594 {
12595 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12596 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12597 (tANI_U8*)(genie - 2),
12598 probe_rsp_ie_len[0], NULL,
12599 eANI_BOOLEAN_FALSE)
12600 == eHAL_STATUS_FAILURE)
12601 {
12602 hddLog(LOGE,
12603 "Could not pass"
12604 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12605 }
12606 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12607 }
12608
12609 if (probe_rsp_ie_len[1] > 0)
12610 {
12611 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12612 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12613 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12614 probe_rsp_ie_len[1], NULL,
12615 eANI_BOOLEAN_FALSE)
12616 == eHAL_STATUS_FAILURE)
12617 {
12618 hddLog(LOGE,
12619 "Could not pass"
12620 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12621 }
12622 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12623 }
12624
12625 if (probe_rsp_ie_len[2] > 0)
12626 {
12627 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12628 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12629 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12630 probe_rsp_ie_len[2], NULL,
12631 eANI_BOOLEAN_FALSE)
12632 == eHAL_STATUS_FAILURE)
12633 {
12634 hddLog(LOGE,
12635 "Could not pass"
12636 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12637 }
12638 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12639 }
12640
12641 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12642 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12643 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12644 {
12645 hddLog(LOGE,
12646 "Could not pass"
12647 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12648 }
12649 }
12650 else
12651 {
12652 // Reset WNI_CFG_PROBE_RSP Flags
12653 wlan_hdd_reset_prob_rspies(pAdapter);
12654
12655 hddLog(VOS_TRACE_LEVEL_INFO,
12656 "%s: No Probe Response IE received in set beacon",
12657 __func__);
12658 }
12659 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012660 break;
12661 case DOT11F_EID_RSN:
12662 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12663 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12664 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12665 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12666 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12667 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012668
12669 /* Appending Extended Capabilities with Interworking bit set
12670 * in Assoc Req.
12671 *
12672 * In assoc req this EXT Cap will only be taken into account if
12673 * interworkingService bit is set to 1. Currently
12674 * driver is only interested in interworkingService capability
12675 * from supplicant. If in future any other EXT Cap info is
12676 * required from supplicat, it needs to be handled while
12677 * sending Assoc Req in LIM.
12678 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012679 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012681 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012682 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012683 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012685 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012686 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012687 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12688 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012689 VOS_ASSERT(0);
12690 return -ENOMEM;
12691 }
12692 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12693 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012695 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12696 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12697 break;
12698 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012699#ifdef FEATURE_WLAN_WAPI
12700 case WLAN_EID_WAPI:
12701 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012702 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 pAdapter->wapi_info.nWapiMode);
12704 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 akmsuiteCount = WPA_GET_LE16(tmp);
12707 tmp = tmp + 1;
12708 akmlist = (int *)(tmp);
12709 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12710 {
12711 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12712 }
12713 else
12714 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012715 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 VOS_ASSERT(0);
12717 return -EINVAL;
12718 }
12719
12720 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12721 {
12722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012723 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012725 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012727 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012729 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12731 }
12732 break;
12733#endif
12734 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012735 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012736 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012737 /* when Unknown IE is received we should break and continue
12738 * to the next IE in the buffer instead we were returning
12739 * so changing this to break */
12740 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 }
12742 genie += eLen;
12743 remLen -= eLen;
12744 }
12745 EXIT();
12746 return 0;
12747}
12748
12749/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012750 * FUNCTION: hdd_isWPAIEPresent
12751 * Parse the received IE to find the WPA IE
12752 *
12753 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012754static bool hdd_isWPAIEPresent(
12755#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12756 const u8 *ie,
12757#else
12758 u8 *ie,
12759#endif
12760 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012761{
12762 v_U8_t eLen = 0;
12763 v_U16_t remLen = ie_len;
12764 v_U8_t elementId = 0;
12765
12766 while (remLen >= 2)
12767 {
12768 elementId = *ie++;
12769 eLen = *ie++;
12770 remLen -= 2;
12771 if (eLen > remLen)
12772 {
12773 hddLog(VOS_TRACE_LEVEL_ERROR,
12774 "%s: IE length is wrong %d", __func__, eLen);
12775 return FALSE;
12776 }
12777 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12778 {
12779 /* OUI - 0x00 0X50 0XF2
12780 WPA Information Element - 0x01
12781 WPA version - 0x01*/
12782 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12783 return TRUE;
12784 }
12785 ie += eLen;
12786 remLen -= eLen;
12787 }
12788 return FALSE;
12789}
12790
12791/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012792 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012793 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012794 * parameters during connect operation.
12795 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012796int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012797 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012798 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012799{
12800 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012801 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 ENTER();
12803
12804 /*set wpa version*/
12805 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12806
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012807 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012809 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 {
12811 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12812 }
12813 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12814 {
12815 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12816 }
12817 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818
12819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 pWextState->wpaVersion);
12821
12822 /*set authentication type*/
12823 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12824
12825 if (0 > status)
12826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012827 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012828 "%s: failed to set authentication type ", __func__);
12829 return status;
12830 }
12831
12832 /*set key mgmt type*/
12833 if (req->crypto.n_akm_suites)
12834 {
12835 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12836 if (0 > status)
12837 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012839 __func__);
12840 return status;
12841 }
12842 }
12843
12844 /*set pairwise cipher type*/
12845 if (req->crypto.n_ciphers_pairwise)
12846 {
12847 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12848 req->crypto.ciphers_pairwise[0], true);
12849 if (0 > status)
12850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012851 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012852 "%s: failed to set unicast cipher type", __func__);
12853 return status;
12854 }
12855 }
12856 else
12857 {
12858 /*Reset previous cipher suite to none*/
12859 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12860 if (0 > status)
12861 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012862 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 "%s: failed to set unicast cipher type", __func__);
12864 return status;
12865 }
12866 }
12867
12868 /*set group cipher type*/
12869 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12870 false);
12871
12872 if (0 > status)
12873 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 __func__);
12876 return status;
12877 }
12878
Chet Lanctot186b5732013-03-18 10:26:30 -070012879#ifdef WLAN_FEATURE_11W
12880 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12881#endif
12882
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12884 if (req->ie_len)
12885 {
12886 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12887 if ( 0 > status)
12888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 __func__);
12891 return status;
12892 }
12893 }
12894
12895 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012896 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 {
12898 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12899 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12900 )
12901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012902 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12904 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 __func__);
12907 return -EOPNOTSUPP;
12908 }
12909 else
12910 {
12911 u8 key_len = req->key_len;
12912 u8 key_idx = req->key_idx;
12913
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012914 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 && (CSR_MAX_NUM_KEY > key_idx)
12916 )
12917 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012918 hddLog(VOS_TRACE_LEVEL_INFO,
12919 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 __func__, key_idx, key_len);
12921 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012922 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012923 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 (u8)key_len;
12926 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12927 }
12928 }
12929 }
12930 }
12931
12932 return status;
12933}
12934
12935/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012936 * FUNCTION: wlan_hdd_try_disconnect
12937 * This function is used to disconnect from previous
12938 * connection
12939 */
12940static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12941{
12942 long ret = 0;
12943 hdd_station_ctx_t *pHddStaCtx;
12944 eMib_dot11DesiredBssType connectedBssType;
12945
12946 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12947
12948 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12949
12950 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12951 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12952 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12953 {
12954 /* Issue disconnect to CSR */
12955 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12956 if( eHAL_STATUS_SUCCESS ==
12957 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12958 pAdapter->sessionId,
12959 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12960 {
12961 ret = wait_for_completion_interruptible_timeout(
12962 &pAdapter->disconnect_comp_var,
12963 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12964 if (0 >= ret)
12965 {
12966 hddLog(LOGE, FL("Failed to receive disconnect event"));
12967 return -EALREADY;
12968 }
12969 }
12970 }
12971 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12972 {
12973 ret = wait_for_completion_interruptible_timeout(
12974 &pAdapter->disconnect_comp_var,
12975 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12976 if (0 >= ret)
12977 {
12978 hddLog(LOGE, FL("Failed to receive disconnect event"));
12979 return -EALREADY;
12980 }
12981 }
12982
12983 return 0;
12984}
12985
12986/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012987 * FUNCTION: __wlan_hdd_cfg80211_connect
12988 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012990static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 struct net_device *ndev,
12992 struct cfg80211_connect_params *req
12993 )
12994{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012995 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012997 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012998 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012999
13000 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013001
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013002 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13003 TRACE_CODE_HDD_CFG80211_CONNECT,
13004 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013005 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013006 "%s: device_mode = %s (%d)", __func__,
13007 hdd_device_modetoString(pAdapter->device_mode),
13008 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013009
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013011 if (!pHddCtx)
13012 {
13013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13014 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013015 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013016 }
13017
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013018 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013019 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013021 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 }
13023
Agarwal Ashish51325b52014-06-16 16:50:49 +053013024 if (vos_max_concurrent_connections_reached()) {
13025 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13026 return -ECONNREFUSED;
13027 }
13028
Jeff Johnson295189b2012-06-20 16:38:30 -070013029#ifdef WLAN_BTAMP_FEATURE
13030 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013031 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013033 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013035 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 }
13037#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013038
13039 //If Device Mode is Station Concurrent Sessions Exit BMps
13040 //P2P Mode will be taken care in Open/close adapter
13041 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013042 (vos_concurrent_open_sessions_running())) {
13043 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13044 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013045 }
13046
13047 /*Try disconnecting if already in connected state*/
13048 status = wlan_hdd_try_disconnect(pAdapter);
13049 if ( 0 > status)
13050 {
13051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13052 " connection"));
13053 return -EALREADY;
13054 }
13055
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013057 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013058
13059 if ( 0 > status)
13060 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013062 __func__);
13063 return status;
13064 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013065 if ( req->channel )
13066 {
13067 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13068 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013069 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070013070 req->channel->hw_value);
13071 }
13072 else
13073 {
13074 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013075 req->ssid_len, req->bssid,
13076 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013078
Sushant Kaushikd7083982015-03-18 14:33:24 +053013079 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 {
13081 //ReEnable BMPS if disabled
13082 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13083 (NULL != pHddCtx))
13084 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013085 if (pHddCtx->hdd_wlan_suspended)
13086 {
13087 hdd_set_pwrparams(pHddCtx);
13088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 //ReEnable Bmps and Imps back
13090 hdd_enable_bmps_imps(pHddCtx);
13091 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 return status;
13094 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013095 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 EXIT();
13097 return status;
13098}
13099
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013100static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13101 struct net_device *ndev,
13102 struct cfg80211_connect_params *req)
13103{
13104 int ret;
13105 vos_ssr_protect(__func__);
13106 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13107 vos_ssr_unprotect(__func__);
13108
13109 return ret;
13110}
Jeff Johnson295189b2012-06-20 16:38:30 -070013111
13112/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013113 * FUNCTION: wlan_hdd_disconnect
13114 * This function is used to issue a disconnect request to SME
13115 */
13116int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13117{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013118 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013119 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013120 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013121 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013122
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013123 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013125 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013126 if (0 != status)
13127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013128 return status;
13129 }
13130
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013131 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13132 {
13133 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13134 pAdapter->sessionId);
13135 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013136 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013137
Agarwal Ashish47d18112014-08-04 19:55:07 +053013138 /* Need to apply spin lock before decreasing active sessions
13139 * as there can be chance for double decrement if context switch
13140 * Calls hdd_DisConnectHandler.
13141 */
13142
13143 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013144 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13145 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013146 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13147 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013148 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13149 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013150
Abhishek Singhf4669da2014-05-26 15:07:49 +053013151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013152 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13153
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013154 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013155
Mihir Shete182a0b22014-08-18 16:08:48 +053013156 /*
13157 * stop tx queues before deleting STA/BSS context from the firmware.
13158 * tx has to be disabled because the firmware can get busy dropping
13159 * the tx frames after BSS/STA has been deleted and will not send
13160 * back a response resulting in WDI timeout
13161 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013162 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013163 netif_tx_disable(pAdapter->dev);
13164 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013165
Mihir Shete182a0b22014-08-18 16:08:48 +053013166 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013167 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13168 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013169 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13170 {
13171 hddLog(VOS_TRACE_LEVEL_INFO,
13172 FL("status = %d, already disconnected"),
13173 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013174
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013175 }
13176 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013177 {
13178 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013179 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013180 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013181 result = -EINVAL;
13182 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013183 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013184 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013185 &pAdapter->disconnect_comp_var,
13186 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013187 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013188 {
13189 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013190 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013191 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013192 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013193 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013194 {
13195 hddLog(VOS_TRACE_LEVEL_ERROR,
13196 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013197 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013198 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013199disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13201 FL("Set HDD connState to eConnectionState_NotConnected"));
13202 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13203
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013204 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013205 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013206}
13207
13208
13209/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013210 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 * This function is used to issue a disconnect request to SME
13212 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013213static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013214 struct net_device *dev,
13215 u16 reason
13216 )
13217{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013219 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013220 tCsrRoamProfile *pRoamProfile;
13221 hdd_station_ctx_t *pHddStaCtx;
13222 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013223#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013224 tANI_U8 staIdx;
13225#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013226
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013228
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013229 if (!pAdapter) {
13230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13231 return -EINVAL;
13232 }
13233
13234 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13235 if (!pHddStaCtx) {
13236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13237 return -EINVAL;
13238 }
13239
13240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13241 status = wlan_hdd_validate_context(pHddCtx);
13242 if (0 != status)
13243 {
13244 return status;
13245 }
13246
13247 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13248
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13250 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13251 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13253 __func__, hdd_device_modetoString(pAdapter->device_mode),
13254 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013255
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13257 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013258
Jeff Johnson295189b2012-06-20 16:38:30 -070013259 if (NULL != pRoamProfile)
13260 {
13261 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013262 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13263 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013265 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013266 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013267 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 switch(reason)
13269 {
13270 case WLAN_REASON_MIC_FAILURE:
13271 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13272 break;
13273
13274 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13275 case WLAN_REASON_DISASSOC_AP_BUSY:
13276 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13277 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13278 break;
13279
13280 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13281 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013282 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013283 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13284 break;
13285
Jeff Johnson295189b2012-06-20 16:38:30 -070013286 default:
13287 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13288 break;
13289 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013290 pScanInfo = &pHddCtx->scan_info;
13291 if (pScanInfo->mScanPending)
13292 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013293 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013294 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013295 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013296 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013297 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013298 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013299#ifdef FEATURE_WLAN_TDLS
13300 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013301 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013302 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013303 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13304 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013305 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013306 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013307 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013309 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013310 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013311 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013312 status = sme_DeleteTdlsPeerSta(
13313 WLAN_HDD_GET_HAL_CTX(pAdapter),
13314 pAdapter->sessionId,
13315 mac);
13316 if (status != eHAL_STATUS_SUCCESS) {
13317 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13318 return -EPERM;
13319 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013320 }
13321 }
13322#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013323 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013324 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13325 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 {
13327 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013328 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 __func__, (int)status );
13330 return -EINVAL;
13331 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013333 else
13334 {
13335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13336 "called while in %d state", __func__,
13337 pHddStaCtx->conn_info.connState);
13338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013339 }
13340 else
13341 {
13342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13343 }
13344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013345 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 return status;
13347}
13348
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013349static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13350 struct net_device *dev,
13351 u16 reason
13352 )
13353{
13354 int ret;
13355 vos_ssr_protect(__func__);
13356 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13357 vos_ssr_unprotect(__func__);
13358
13359 return ret;
13360}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013361
Jeff Johnson295189b2012-06-20 16:38:30 -070013362/*
13363 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013364 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 * settings in IBSS mode.
13366 */
13367static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013368 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 struct cfg80211_ibss_params *params
13370 )
13371{
13372 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013373 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13375 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013376
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 ENTER();
13378
13379 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013380 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013381
13382 if (params->ie_len && ( NULL != params->ie) )
13383 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013384 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13385 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 {
13387 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13388 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13389 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013390 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013392 tDot11fIEWPA dot11WPAIE;
13393 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013394 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013395
Wilson Yang00256342013-10-10 23:13:38 -070013396 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013397 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13398 params->ie_len, DOT11F_EID_WPA);
13399 if ( NULL != ie )
13400 {
13401 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13402 // Unpack the WPA IE
13403 //Skip past the EID byte and length byte - and four byte WiFi OUI
13404 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13405 &ie[2+4],
13406 ie[1] - 4,
13407 &dot11WPAIE);
13408 /*Extract the multicast cipher, the encType for unicast
13409 cipher for wpa-none is none*/
13410 encryptionType =
13411 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13412 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013414
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13416
13417 if (0 > status)
13418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 __func__);
13421 return status;
13422 }
13423 }
13424
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013425 pWextState->roamProfile.AuthType.authType[0] =
13426 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13428
13429 if (params->privacy)
13430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013431 /* Security enabled IBSS, At this time there is no information available
13432 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013434 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013436 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 *enable privacy bit in beacons */
13438
13439 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13440 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013441 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13442 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13444 pWextState->roamProfile.EncryptionType.numEntries = 1;
13445 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 return status;
13447}
13448
13449/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013450 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013451 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013453static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 struct net_device *dev,
13455 struct cfg80211_ibss_params *params
13456 )
13457{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013458 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013459 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13460 tCsrRoamProfile *pRoamProfile;
13461 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013462 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13463 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013464 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013465
13466 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013467
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013468 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13469 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13470 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013471 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013472 "%s: device_mode = %s (%d)", __func__,
13473 hdd_device_modetoString(pAdapter->device_mode),
13474 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013475
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013476 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013477 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013479 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 }
13481
13482 if (NULL == pWextState)
13483 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013484 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 __func__);
13486 return -EIO;
13487 }
13488
Agarwal Ashish51325b52014-06-16 16:50:49 +053013489 if (vos_max_concurrent_connections_reached()) {
13490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13491 return -ECONNREFUSED;
13492 }
13493
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013494 /*Try disconnecting if already in connected state*/
13495 status = wlan_hdd_try_disconnect(pAdapter);
13496 if ( 0 > status)
13497 {
13498 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13499 " IBSS connection"));
13500 return -EALREADY;
13501 }
13502
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 pRoamProfile = &pWextState->roamProfile;
13504
13505 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013507 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013508 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013509 return -EINVAL;
13510 }
13511
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013512 /* BSSID is provided by upper layers hence no need to AUTO generate */
13513 if (NULL != params->bssid) {
13514 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13515 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13516 hddLog (VOS_TRACE_LEVEL_ERROR,
13517 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13518 return -EIO;
13519 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013520 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013521 }
krunal sonie9002db2013-11-25 14:24:17 -080013522 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13523 {
13524 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13525 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13526 {
13527 hddLog (VOS_TRACE_LEVEL_ERROR,
13528 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13529 return -EIO;
13530 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013531
13532 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013533 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013534 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013535 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013536
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013538 if (NULL !=
13539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13540 params->chandef.chan)
13541#else
13542 params->channel)
13543#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 {
13545 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013546 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13547 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13548 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13549 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013550
13551 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013552 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013553 ieee80211_frequency_to_channel(
13554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13555 params->chandef.chan->center_freq);
13556#else
13557 params->channel->center_freq);
13558#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013559
13560 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13561 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013563 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13564 __func__);
13565 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013567
13568 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013570 if (channelNum == validChan[indx])
13571 {
13572 break;
13573 }
13574 }
13575 if (indx >= numChans)
13576 {
13577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 __func__, channelNum);
13579 return -EINVAL;
13580 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013581 /* Set the Operational Channel */
13582 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13583 channelNum);
13584 pRoamProfile->ChannelInfo.numOfChannels = 1;
13585 pHddStaCtx->conn_info.operationChannel = channelNum;
13586 pRoamProfile->ChannelInfo.ChannelList =
13587 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 }
13589
13590 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013591 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 if (status < 0)
13593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 __func__);
13596 return status;
13597 }
13598
13599 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013600 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013601 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013602 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013603
13604 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013607 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013608 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013609}
13610
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013611static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13612 struct net_device *dev,
13613 struct cfg80211_ibss_params *params
13614 )
13615{
13616 int ret = 0;
13617
13618 vos_ssr_protect(__func__);
13619 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13620 vos_ssr_unprotect(__func__);
13621
13622 return ret;
13623}
13624
Jeff Johnson295189b2012-06-20 16:38:30 -070013625/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013626 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013627 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013629static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 struct net_device *dev
13631 )
13632{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013634 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13635 tCsrRoamProfile *pRoamProfile;
13636 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013637 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013638
13639 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013640
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013641 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13642 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13643 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013645 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013647 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013648 }
13649
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013650 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13651 hdd_device_modetoString(pAdapter->device_mode),
13652 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 if (NULL == pWextState)
13654 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013655 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 __func__);
13657 return -EIO;
13658 }
13659
13660 pRoamProfile = &pWextState->roamProfile;
13661
13662 /* Issue disconnect only if interface type is set to IBSS */
13663 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013666 __func__);
13667 return -EINVAL;
13668 }
13669
13670 /* Issue Disconnect request */
13671 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13672 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13673 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013675 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 return 0;
13677}
13678
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013679static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13680 struct net_device *dev
13681 )
13682{
13683 int ret = 0;
13684
13685 vos_ssr_protect(__func__);
13686 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13687 vos_ssr_unprotect(__func__);
13688
13689 return ret;
13690}
13691
Jeff Johnson295189b2012-06-20 16:38:30 -070013692/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013693 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 * This function is used to set the phy parameters
13695 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13696 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013697static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 u32 changed)
13699{
13700 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13701 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013702 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013703
13704 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013705
13706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013707 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13708 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013709
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013710 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013711 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013712 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013713 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013714 }
13715
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13717 {
13718 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13719 WNI_CFG_RTS_THRESHOLD_STAMAX :
13720 wiphy->rts_threshold;
13721
13722 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013723 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013725 hddLog(VOS_TRACE_LEVEL_ERROR,
13726 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 __func__, rts_threshold);
13728 return -EINVAL;
13729 }
13730
13731 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13732 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013733 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013735 hddLog(VOS_TRACE_LEVEL_ERROR,
13736 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 __func__, rts_threshold);
13738 return -EIO;
13739 }
13740
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013741 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 rts_threshold);
13743 }
13744
13745 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13746 {
13747 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13748 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13749 wiphy->frag_threshold;
13750
13751 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013752 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013754 hddLog(VOS_TRACE_LEVEL_ERROR,
13755 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 frag_threshold);
13757 return -EINVAL;
13758 }
13759
13760 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13761 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013762 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013764 hddLog(VOS_TRACE_LEVEL_ERROR,
13765 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013766 __func__, frag_threshold);
13767 return -EIO;
13768 }
13769
13770 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13771 frag_threshold);
13772 }
13773
13774 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13775 || (changed & WIPHY_PARAM_RETRY_LONG))
13776 {
13777 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13778 wiphy->retry_short :
13779 wiphy->retry_long;
13780
13781 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13782 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 __func__, retry_value);
13786 return -EINVAL;
13787 }
13788
13789 if (changed & WIPHY_PARAM_RETRY_SHORT)
13790 {
13791 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13792 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013793 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013795 hddLog(VOS_TRACE_LEVEL_ERROR,
13796 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 __func__, retry_value);
13798 return -EIO;
13799 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013800 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 __func__, retry_value);
13802 }
13803 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13804 {
13805 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13806 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013809 hddLog(VOS_TRACE_LEVEL_ERROR,
13810 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 __func__, retry_value);
13812 return -EIO;
13813 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013814 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 __func__, retry_value);
13816 }
13817 }
13818
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013819 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 return 0;
13821}
13822
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013823static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13824 u32 changed)
13825{
13826 int ret;
13827
13828 vos_ssr_protect(__func__);
13829 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13830 vos_ssr_unprotect(__func__);
13831
13832 return ret;
13833}
13834
Jeff Johnson295189b2012-06-20 16:38:30 -070013835/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013836 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 * This function is used to set the txpower
13838 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013839static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013840#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13841 struct wireless_dev *wdev,
13842#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013843#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013844 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013845#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013847#endif
13848 int dbm)
13849{
13850 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013851 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13853 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013854 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013855
13856 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013857
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013858 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13859 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13860 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013861 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013862 if (0 != status)
13863 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013864 return status;
13865 }
13866
13867 hHal = pHddCtx->hHal;
13868
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013869 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13870 dbm, ccmCfgSetCallback,
13871 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013873 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13875 return -EIO;
13876 }
13877
13878 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13879 dbm);
13880
13881 switch(type)
13882 {
13883 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13884 /* Fall through */
13885 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13886 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13889 __func__);
13890 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013891 }
13892 break;
13893 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 __func__);
13896 return -EOPNOTSUPP;
13897 break;
13898 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13900 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 return -EIO;
13902 }
13903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013904 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 return 0;
13906}
13907
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013908static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13909#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13910 struct wireless_dev *wdev,
13911#endif
13912#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13913 enum tx_power_setting type,
13914#else
13915 enum nl80211_tx_power_setting type,
13916#endif
13917 int dbm)
13918{
13919 int ret;
13920 vos_ssr_protect(__func__);
13921 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13922#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13923 wdev,
13924#endif
13925#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13926 type,
13927#else
13928 type,
13929#endif
13930 dbm);
13931 vos_ssr_unprotect(__func__);
13932
13933 return ret;
13934}
13935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013937 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 * This function is used to read the txpower
13939 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013940static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013941#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13942 struct wireless_dev *wdev,
13943#endif
13944 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013945{
13946
13947 hdd_adapter_t *pAdapter;
13948 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013949 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013950
Jeff Johnsone7245742012-09-05 17:12:55 -070013951 ENTER();
13952
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013953 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013954 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013955 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013956 *dbm = 0;
13957 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013958 }
13959
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13961 if (NULL == pAdapter)
13962 {
13963 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13964 return -ENOENT;
13965 }
13966
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013967 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13968 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13969 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 wlan_hdd_get_classAstats(pAdapter);
13971 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13972
Jeff Johnsone7245742012-09-05 17:12:55 -070013973 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 return 0;
13975}
13976
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013977static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13978#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13979 struct wireless_dev *wdev,
13980#endif
13981 int *dbm)
13982{
13983 int ret;
13984
13985 vos_ssr_protect(__func__);
13986 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13987#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13988 wdev,
13989#endif
13990 dbm);
13991 vos_ssr_unprotect(__func__);
13992
13993 return ret;
13994}
13995
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013996static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013997#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13998 const u8* mac,
13999#else
14000 u8* mac,
14001#endif
14002 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070014003{
14004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14005 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14006 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053014007 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014008
14009 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
14010 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070014011
14012 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
14013 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
14014 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
14015 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
14016 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
14017 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
14018 tANI_U16 maxRate = 0;
14019 tANI_U16 myRate;
14020 tANI_U16 currentRate = 0;
14021 tANI_U8 maxSpeedMCS = 0;
14022 tANI_U8 maxMCSIdx = 0;
14023 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014024 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014025 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014026 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014027
Leo Chang6f8870f2013-03-26 18:11:36 -070014028#ifdef WLAN_FEATURE_11AC
14029 tANI_U32 vht_mcs_map;
14030 eDataRate11ACMaxMcs vhtMaxMcs;
14031#endif /* WLAN_FEATURE_11AC */
14032
Jeff Johnsone7245742012-09-05 17:12:55 -070014033 ENTER();
14034
Jeff Johnson295189b2012-06-20 16:38:30 -070014035 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14036 (0 == ssidlen))
14037 {
14038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14039 " Invalid ssidlen, %d", __func__, ssidlen);
14040 /*To keep GUI happy*/
14041 return 0;
14042 }
14043
Mukul Sharma811205f2014-07-09 21:07:30 +053014044 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14045 {
14046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14047 "%s: Roaming in progress, so unable to proceed this request", __func__);
14048 return 0;
14049 }
14050
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014051 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014052 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014054 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014055 }
14056
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014057 wlan_hdd_get_station_stats(pAdapter);
14058 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014059
Kiet Lam3b17fc82013-09-27 05:24:08 +053014060 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14061 sinfo->filled |= STATION_INFO_SIGNAL;
14062
c_hpothu09f19542014-05-30 21:53:31 +053014063 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014064 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14065 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014066 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014067 {
14068 rate_flags = pAdapter->maxRateFlags;
14069 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014070
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 //convert to the UI units of 100kbps
14072 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14073
14074#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014075 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 -070014076 sinfo->signal,
14077 pCfg->reportMaxLinkSpeed,
14078 myRate,
14079 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014080 (int) pCfg->linkSpeedRssiMid,
14081 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014082 (int) rate_flags,
14083 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014084#endif //LINKSPEED_DEBUG_ENABLED
14085
14086 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14087 {
14088 // we do not want to necessarily report the current speed
14089 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14090 {
14091 // report the max possible speed
14092 rssidx = 0;
14093 }
14094 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14095 {
14096 // report the max possible speed with RSSI scaling
14097 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14098 {
14099 // report the max possible speed
14100 rssidx = 0;
14101 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014102 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 {
14104 // report middle speed
14105 rssidx = 1;
14106 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014107 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14108 {
14109 // report middle speed
14110 rssidx = 2;
14111 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 else
14113 {
14114 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014115 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117 }
14118 else
14119 {
14120 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14121 hddLog(VOS_TRACE_LEVEL_ERROR,
14122 "%s: Invalid value for reportMaxLinkSpeed: %u",
14123 __func__, pCfg->reportMaxLinkSpeed);
14124 rssidx = 0;
14125 }
14126
14127 maxRate = 0;
14128
14129 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014130 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14131 OperationalRates, &ORLeng))
14132 {
14133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14134 /*To keep GUI happy*/
14135 return 0;
14136 }
14137
Jeff Johnson295189b2012-06-20 16:38:30 -070014138 for (i = 0; i < ORLeng; i++)
14139 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014140 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014141 {
14142 /* Validate Rate Set */
14143 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14144 {
14145 currentRate = supported_data_rate[j].supported_rate[rssidx];
14146 break;
14147 }
14148 }
14149 /* Update MAX rate */
14150 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14151 }
14152
14153 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014154 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14155 ExtendedRates, &ERLeng))
14156 {
14157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14158 /*To keep GUI happy*/
14159 return 0;
14160 }
14161
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 for (i = 0; i < ERLeng; i++)
14163 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014164 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014165 {
14166 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14167 {
14168 currentRate = supported_data_rate[j].supported_rate[rssidx];
14169 break;
14170 }
14171 }
14172 /* Update MAX rate */
14173 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14174 }
c_hpothu79aab322014-07-14 21:11:01 +053014175
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014176 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014177 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014178 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014179 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 {
c_hpothu79aab322014-07-14 21:11:01 +053014181 if (rate_flags & eHAL_TX_RATE_VHT80)
14182 mode = 2;
14183 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14184 mode = 1;
14185 else
14186 mode = 0;
14187
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014188 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14189 MCSRates, &MCSLeng))
14190 {
14191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14192 /*To keep GUI happy*/
14193 return 0;
14194 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014196#ifdef WLAN_FEATURE_11AC
14197 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014198 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014199 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014200 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014201 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014202 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014204 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014205 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014206 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014207 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014208 maxMCSIdx = 7;
14209 }
14210 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14211 {
14212 maxMCSIdx = 8;
14213 }
14214 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14215 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014216 //VHT20 is supporting 0~8
14217 if (rate_flags & eHAL_TX_RATE_VHT20)
14218 maxMCSIdx = 8;
14219 else
14220 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014221 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014222
c_hpothu79aab322014-07-14 21:11:01 +053014223 if (0 != rssidx)/*check for scaled */
14224 {
14225 //get middle rate MCS index if rssi=1/2
14226 for (i=0; i <= maxMCSIdx; i++)
14227 {
14228 if (sinfo->signal <= rssiMcsTbl[mode][i])
14229 {
14230 maxMCSIdx = i;
14231 break;
14232 }
14233 }
14234 }
14235
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014236 if (rate_flags & eHAL_TX_RATE_VHT80)
14237 {
14238 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14239 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14240 }
14241 else if (rate_flags & eHAL_TX_RATE_VHT40)
14242 {
14243 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14244 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14245 }
14246 else if (rate_flags & eHAL_TX_RATE_VHT20)
14247 {
14248 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14249 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14250 }
14251
Leo Chang6f8870f2013-03-26 18:11:36 -070014252 maxSpeedMCS = 1;
14253 if (currentRate > maxRate)
14254 {
14255 maxRate = currentRate;
14256 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014257
Leo Chang6f8870f2013-03-26 18:11:36 -070014258 }
14259 else
14260#endif /* WLAN_FEATURE_11AC */
14261 {
14262 if (rate_flags & eHAL_TX_RATE_HT40)
14263 {
14264 rateFlag |= 1;
14265 }
14266 if (rate_flags & eHAL_TX_RATE_SGI)
14267 {
14268 rateFlag |= 2;
14269 }
14270
Girish Gowli01abcee2014-07-31 20:18:55 +053014271 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014272 if (rssidx == 1 || rssidx == 2)
14273 {
14274 //get middle rate MCS index if rssi=1/2
14275 for (i=0; i <= 7; i++)
14276 {
14277 if (sinfo->signal <= rssiMcsTbl[mode][i])
14278 {
14279 temp = i+1;
14280 break;
14281 }
14282 }
14283 }
c_hpothu79aab322014-07-14 21:11:01 +053014284
14285 for (i = 0; i < MCSLeng; i++)
14286 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014287 for (j = 0; j < temp; j++)
14288 {
14289 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14290 {
14291 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014292 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014293 break;
14294 }
14295 }
14296 if ((j < temp) && (currentRate > maxRate))
14297 {
14298 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014301 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 }
14303 }
14304
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014305 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14306 {
14307 maxRate = myRate;
14308 maxSpeedMCS = 1;
14309 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14310 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014312 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 {
14314 maxRate = myRate;
14315 if (rate_flags & eHAL_TX_RATE_LEGACY)
14316 {
14317 maxSpeedMCS = 0;
14318 }
14319 else
14320 {
14321 maxSpeedMCS = 1;
14322 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14323 }
14324 }
14325
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014326 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014327 {
14328 sinfo->txrate.legacy = maxRate;
14329#ifdef LINKSPEED_DEBUG_ENABLED
14330 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14331#endif //LINKSPEED_DEBUG_ENABLED
14332 }
14333 else
14334 {
14335 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014336#ifdef WLAN_FEATURE_11AC
14337 sinfo->txrate.nss = 1;
14338 if (rate_flags & eHAL_TX_RATE_VHT80)
14339 {
14340 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014341 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014342 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014343 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014344 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014345 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14346 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14347 }
14348 else if (rate_flags & eHAL_TX_RATE_VHT20)
14349 {
14350 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14351 }
14352#endif /* WLAN_FEATURE_11AC */
14353 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14354 {
14355 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14356 if (rate_flags & eHAL_TX_RATE_HT40)
14357 {
14358 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14359 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014360 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 if (rate_flags & eHAL_TX_RATE_SGI)
14362 {
14363 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14364 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014365
Jeff Johnson295189b2012-06-20 16:38:30 -070014366#ifdef LINKSPEED_DEBUG_ENABLED
14367 pr_info("Reporting MCS rate %d flags %x\n",
14368 sinfo->txrate.mcs,
14369 sinfo->txrate.flags );
14370#endif //LINKSPEED_DEBUG_ENABLED
14371 }
14372 }
14373 else
14374 {
14375 // report current rate instead of max rate
14376
14377 if (rate_flags & eHAL_TX_RATE_LEGACY)
14378 {
14379 //provide to the UI in units of 100kbps
14380 sinfo->txrate.legacy = myRate;
14381#ifdef LINKSPEED_DEBUG_ENABLED
14382 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14383#endif //LINKSPEED_DEBUG_ENABLED
14384 }
14385 else
14386 {
14387 //must be MCS
14388 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014389#ifdef WLAN_FEATURE_11AC
14390 sinfo->txrate.nss = 1;
14391 if (rate_flags & eHAL_TX_RATE_VHT80)
14392 {
14393 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14394 }
14395 else
14396#endif /* WLAN_FEATURE_11AC */
14397 {
14398 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 if (rate_flags & eHAL_TX_RATE_SGI)
14401 {
14402 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14403 }
14404 if (rate_flags & eHAL_TX_RATE_HT40)
14405 {
14406 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14407 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014408#ifdef WLAN_FEATURE_11AC
14409 else if (rate_flags & eHAL_TX_RATE_VHT80)
14410 {
14411 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14412 }
14413#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014414#ifdef LINKSPEED_DEBUG_ENABLED
14415 pr_info("Reporting actual MCS rate %d flags %x\n",
14416 sinfo->txrate.mcs,
14417 sinfo->txrate.flags );
14418#endif //LINKSPEED_DEBUG_ENABLED
14419 }
14420 }
14421 sinfo->filled |= STATION_INFO_TX_BITRATE;
14422
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014423 sinfo->tx_packets =
14424 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14425 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14426 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14427 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14428
14429 sinfo->tx_retries =
14430 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14431 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14432 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14433 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14434
14435 sinfo->tx_failed =
14436 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14437 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14438 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14439 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14440
14441 sinfo->filled |=
14442 STATION_INFO_TX_PACKETS |
14443 STATION_INFO_TX_RETRIES |
14444 STATION_INFO_TX_FAILED;
14445
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014446 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14447 TRACE_CODE_HDD_CFG80211_GET_STA,
14448 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014449 EXIT();
14450 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014451}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014452#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14453static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14454 const u8* mac, struct station_info *sinfo)
14455#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014456static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14457 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014458#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014459{
14460 int ret;
14461
14462 vos_ssr_protect(__func__);
14463 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14464 vos_ssr_unprotect(__func__);
14465
14466 return ret;
14467}
14468
14469static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014470 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014471{
14472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014473 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014474 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014475 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014476
Jeff Johnsone7245742012-09-05 17:12:55 -070014477 ENTER();
14478
Jeff Johnson295189b2012-06-20 16:38:30 -070014479 if (NULL == pAdapter)
14480 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014482 return -ENODEV;
14483 }
14484
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014485 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14486 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14487 pAdapter->sessionId, timeout));
14488
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014489 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014490 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014491 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014492 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014493 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014494 }
14495
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014496 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14497 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14498 (pHddCtx->cfg_ini->fhostArpOffload) &&
14499 (eConnectionState_Associated ==
14500 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14501 {
Amar Singhald53568e2013-09-26 11:03:45 -070014502
14503 hddLog(VOS_TRACE_LEVEL_INFO,
14504 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014505 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014506 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14507 {
14508 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014509 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014510 __func__, vos_status);
14511 }
14512 }
14513
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 /**The get power cmd from the supplicant gets updated by the nl only
14515 *on successful execution of the function call
14516 *we are oppositely mapped w.r.t mode in the driver
14517 **/
14518 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14519
14520 if (VOS_STATUS_E_FAILURE == vos_status)
14521 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14523 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 return -EINVAL;
14525 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014526 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 return 0;
14528}
14529
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014530static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14531 struct net_device *dev, bool mode, int timeout)
14532{
14533 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014534
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014535 vos_ssr_protect(__func__);
14536 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14537 vos_ssr_unprotect(__func__);
14538
14539 return ret;
14540}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014541static const struct
14542nla_policy
14543qca_wlan_vendor_get_wifi_info_policy[
14544 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
14545 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
14546 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
14547};
14548
14549/**
14550 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
14551 * @wiphy: pointer to wireless wiphy structure.
14552 * @wdev: pointer to wireless_dev structure.
14553 * @data: Pointer to the data to be passed via vendor interface
14554 * @data_len:Length of the data to be passed
14555 *
14556 * This is called when wlan driver needs to send wifi driver related info
14557 * (driver/fw version) to the user space application upon request.
14558 *
14559 * Return: Return the Success or Failure code.
14560 */
14561static int
14562wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
14563 struct wireless_dev *wdev,
14564 const void *data, int data_len)
14565{
14566 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
14567 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
14568 tSirVersionString version;
14569 uint32 version_len;
14570 uint8 attr;
14571 int status;
14572 struct sk_buff *reply_skb = NULL;
14573
14574 if (VOS_FTM_MODE == hdd_get_conparam()) {
14575 hddLog(LOGE, FL("Command not allowed in FTM mode"));
14576 return -EINVAL;
14577 }
14578
14579 status = wlan_hdd_validate_context(hdd_ctx);
14580 if (0 != status) {
14581 hddLog(LOGE, FL("HDD context is not valid"));
14582 return -EINVAL;
14583 }
14584
14585 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
14586 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
14587 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
14588 return -EINVAL;
14589 }
14590
14591 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
14592 hddLog(LOG1, FL("Rcvd req for Driver version "
14593 "Driver version is %s"),QWLAN_VERSIONSTR);
14594 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
14595 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
14596 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
14597 hddLog(LOG1, FL("Rcvd req for FW version "
14598 "FW version is %s"), hdd_ctx->fw_Version);
14599 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
14600 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
14601 } else {
14602 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
14603 return -EINVAL;
14604 }
14605
14606 version_len = strlen(version);
14607 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
14608 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
14609 if (!reply_skb) {
14610 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
14611 return -ENOMEM;
14612 }
14613
14614 if (nla_put(reply_skb, attr, version_len, version)) {
14615 hddLog(LOGE, FL("nla put fail"));
14616 kfree_skb(reply_skb);
14617 return -EINVAL;
14618 }
14619
14620 return cfg80211_vendor_cmd_reply(reply_skb);
14621}
14622
Jeff Johnson295189b2012-06-20 16:38:30 -070014623#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014624static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14625 struct net_device *netdev,
14626 u8 key_index)
14627{
14628 ENTER();
14629 return 0;
14630}
14631
Jeff Johnson295189b2012-06-20 16:38:30 -070014632static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014633 struct net_device *netdev,
14634 u8 key_index)
14635{
14636 int ret;
14637 vos_ssr_protect(__func__);
14638 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14639 vos_ssr_unprotect(__func__);
14640 return ret;
14641}
14642#endif //LINUX_VERSION_CODE
14643
14644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14645static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14646 struct net_device *dev,
14647 struct ieee80211_txq_params *params)
14648{
14649 ENTER();
14650 return 0;
14651}
14652#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14653static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14654 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014655{
Jeff Johnsone7245742012-09-05 17:12:55 -070014656 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 return 0;
14658}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014659#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014660
14661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14662static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014663 struct net_device *dev,
14664 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014665{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014666 int ret;
14667
14668 vos_ssr_protect(__func__);
14669 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14670 vos_ssr_unprotect(__func__);
14671 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014672}
14673#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14674static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14675 struct ieee80211_txq_params *params)
14676{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014677 int ret;
14678
14679 vos_ssr_protect(__func__);
14680 ret = __wlan_hdd_set_txq_params(wiphy, params);
14681 vos_ssr_unprotect(__func__);
14682 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014683}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014684#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014685
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014686static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014687 struct net_device *dev,
14688 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014689{
14690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014691 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014692 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014693 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014694 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014695 v_CONTEXT_t pVosContext = NULL;
14696 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014697
Jeff Johnsone7245742012-09-05 17:12:55 -070014698 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014699
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014700 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 return -EINVAL;
14704 }
14705
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014706 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14707 TRACE_CODE_HDD_CFG80211_DEL_STA,
14708 pAdapter->sessionId, pAdapter->device_mode));
14709
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14711 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014712 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014713 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014714 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014715 }
14716
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014718 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 )
14720 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014721 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14722 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14723 if(pSapCtx == NULL){
14724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14725 FL("psapCtx is NULL"));
14726 return -ENOENT;
14727 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014728 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014729 {
14730 v_U16_t i;
14731 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14732 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014733 if ((pSapCtx->aStaInfo[i].isUsed) &&
14734 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014736 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014737 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014738 ETHER_ADDR_LEN);
14739
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014741 "%s: Delete STA with MAC::"
14742 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014743 __func__,
14744 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14745 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014746 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014747 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014748 }
14749 }
14750 }
14751 else
14752 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014753
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014754 vos_status = hdd_softap_GetStaId(pAdapter,
14755 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014756 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14757 {
14758 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014759 "%s: Skip this DEL STA as this is not used::"
14760 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014761 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014762 return -ENOENT;
14763 }
14764
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014765 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014766 {
14767 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014768 "%s: Skip this DEL STA as deauth is in progress::"
14769 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014770 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014771 return -ENOENT;
14772 }
14773
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014774 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014775
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 hddLog(VOS_TRACE_LEVEL_INFO,
14777 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014778 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014780 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014781
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014782 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014783 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14784 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014785 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014786 hddLog(VOS_TRACE_LEVEL_INFO,
14787 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014788 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014789 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014790 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014791 return -ENOENT;
14792 }
14793
Jeff Johnson295189b2012-06-20 16:38:30 -070014794 }
14795 }
14796
14797 EXIT();
14798
14799 return 0;
14800}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014801
14802#ifdef CFG80211_DEL_STA_V2
14803static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14804 struct net_device *dev,
14805 struct station_del_parameters *param)
14806#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014807#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14808static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14809 struct net_device *dev, const u8 *mac)
14810#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014811static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14812 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014813#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014814#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014815{
14816 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014817 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014818
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014819 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014820
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014821#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014822 if (NULL == param) {
14823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014824 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014825 return -EINVAL;
14826 }
14827
14828 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14829 param->subtype, &delStaParams);
14830
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014831#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014832 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014833 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014834#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014835 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14836
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014837 vos_ssr_unprotect(__func__);
14838
14839 return ret;
14840}
14841
14842static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014843 struct net_device *dev,
14844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14845 const u8 *mac,
14846#else
14847 u8 *mac,
14848#endif
14849 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014850{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014851 hdd_adapter_t *pAdapter;
14852 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014853 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014854#ifdef FEATURE_WLAN_TDLS
14855 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014856
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014857 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014858
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014859 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14860 if (NULL == pAdapter)
14861 {
14862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14863 "%s: Adapter is NULL",__func__);
14864 return -EINVAL;
14865 }
14866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14867 status = wlan_hdd_validate_context(pHddCtx);
14868 if (0 != status)
14869 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014870 return status;
14871 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14874 TRACE_CODE_HDD_CFG80211_ADD_STA,
14875 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014876 mask = params->sta_flags_mask;
14877
14878 set = params->sta_flags_set;
14879
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014881 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14882 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014883
14884 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14885 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014886 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014887 }
14888 }
14889#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014890 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014891 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014892}
14893
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14895static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14896 struct net_device *dev, const u8 *mac,
14897 struct station_parameters *params)
14898#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014899static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14900 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014901#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014902{
14903 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014904
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014905 vos_ssr_protect(__func__);
14906 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14907 vos_ssr_unprotect(__func__);
14908
14909 return ret;
14910}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014911#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014912
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014913static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014914 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014915{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14917 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014918 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014919 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014920 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014921 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014922
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014923 ENTER();
14924
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014925 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014926 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014927 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014929 return -EINVAL;
14930 }
14931
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014932 if (!pmksa) {
14933 hddLog(LOGE, FL("pmksa is NULL"));
14934 return -EINVAL;
14935 }
14936
14937 if (!pmksa->bssid || !pmksa->pmkid) {
14938 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14939 pmksa->bssid, pmksa->pmkid);
14940 return -EINVAL;
14941 }
14942
14943 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14944 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14945
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014946 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14947 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014948 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014950 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014951 }
14952
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014953 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014954 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14955
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014956 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14957 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014958
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014959 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014960 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014961 &pmk_id, 1, FALSE);
14962
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014963 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14964 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14965 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014967 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014968 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014969}
14970
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014971static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14972 struct cfg80211_pmksa *pmksa)
14973{
14974 int ret;
14975
14976 vos_ssr_protect(__func__);
14977 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14978 vos_ssr_unprotect(__func__);
14979
14980 return ret;
14981}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014982
Wilson Yang6507c4e2013-10-01 20:11:19 -070014983
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014984static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014985 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014986{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014987 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14988 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014989 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014990 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014991
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014992 ENTER();
14993
Wilson Yang6507c4e2013-10-01 20:11:19 -070014994 /* Validate pAdapter */
14995 if (NULL == pAdapter)
14996 {
14997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14998 return -EINVAL;
14999 }
15000
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015001 if (!pmksa) {
15002 hddLog(LOGE, FL("pmksa is NULL"));
15003 return -EINVAL;
15004 }
15005
15006 if (!pmksa->bssid) {
15007 hddLog(LOGE, FL("pmksa->bssid is NULL"));
15008 return -EINVAL;
15009 }
15010
Kiet Lam98c46a12014-10-31 15:34:57 -070015011 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
15012 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15013
Wilson Yang6507c4e2013-10-01 20:11:19 -070015014 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15015 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015016 if (0 != status)
15017 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015018 return status;
15019 }
15020
15021 /*Retrieve halHandle*/
15022 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15023
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15025 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
15026 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015027 /* Delete the PMKID CSR cache */
15028 if (eHAL_STATUS_SUCCESS !=
15029 sme_RoamDelPMKIDfromCache(halHandle,
15030 pAdapter->sessionId, pmksa->bssid, FALSE)) {
15031 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
15032 MAC_ADDR_ARRAY(pmksa->bssid));
15033 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015034 }
15035
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015036 EXIT();
15037 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015038}
15039
Wilson Yang6507c4e2013-10-01 20:11:19 -070015040
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015041static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
15042 struct cfg80211_pmksa *pmksa)
15043{
15044 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015045
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015046 vos_ssr_protect(__func__);
15047 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
15048 vos_ssr_unprotect(__func__);
15049
15050 return ret;
15051
15052}
15053
15054static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015055{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15057 tHalHandle halHandle;
15058 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015059 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015060
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015061 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070015062
15063 /* Validate pAdapter */
15064 if (NULL == pAdapter)
15065 {
15066 hddLog(VOS_TRACE_LEVEL_ERROR,
15067 "%s: Invalid Adapter" ,__func__);
15068 return -EINVAL;
15069 }
15070
15071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15072 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015073 if (0 != status)
15074 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015075 return status;
15076 }
15077
15078 /*Retrieve halHandle*/
15079 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15080
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015081 /* Flush the PMKID cache in CSR */
15082 if (eHAL_STATUS_SUCCESS !=
15083 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
15084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
15085 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015086 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015087 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080015088 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015089}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015090
15091static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
15092{
15093 int ret;
15094
15095 vos_ssr_protect(__func__);
15096 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
15097 vos_ssr_unprotect(__func__);
15098
15099 return ret;
15100}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015101#endif
15102
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015103#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015104static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15105 struct net_device *dev,
15106 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015107{
15108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15109 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015110 hdd_context_t *pHddCtx;
15111 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015112
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015113 ENTER();
15114
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015115 if (NULL == pAdapter)
15116 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015118 return -ENODEV;
15119 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015120 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15121 ret = wlan_hdd_validate_context(pHddCtx);
15122 if (0 != ret)
15123 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015124 return ret;
15125 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015126 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015127 if (NULL == pHddStaCtx)
15128 {
15129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15130 return -EINVAL;
15131 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015132
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015133 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15134 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15135 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015136 // Added for debug on reception of Re-assoc Req.
15137 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15138 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015139 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015140 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015141 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015142 }
15143
15144#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015145 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015146 ftie->ie_len);
15147#endif
15148
15149 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015150 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15151 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015152 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015153
15154 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015155 return 0;
15156}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015157
15158static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15159 struct net_device *dev,
15160 struct cfg80211_update_ft_ies_params *ftie)
15161{
15162 int ret;
15163
15164 vos_ssr_protect(__func__);
15165 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15166 vos_ssr_unprotect(__func__);
15167
15168 return ret;
15169}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015170#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015171
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015172#ifdef FEATURE_WLAN_SCAN_PNO
15173
15174void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15175 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15176{
15177 int ret;
15178 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15179 hdd_context_t *pHddCtx;
15180
Nirav Shah80830bf2013-12-31 16:35:12 +053015181 ENTER();
15182
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015183 if (NULL == pAdapter)
15184 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015186 "%s: HDD adapter is Null", __func__);
15187 return ;
15188 }
15189
15190 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15191 if (NULL == pHddCtx)
15192 {
15193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15194 "%s: HDD context is Null!!!", __func__);
15195 return ;
15196 }
15197
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015198 spin_lock(&pHddCtx->schedScan_lock);
15199 if (TRUE == pHddCtx->isWiphySuspended)
15200 {
15201 pHddCtx->isSchedScanUpdatePending = TRUE;
15202 spin_unlock(&pHddCtx->schedScan_lock);
15203 hddLog(VOS_TRACE_LEVEL_INFO,
15204 "%s: Update cfg80211 scan database after it resume", __func__);
15205 return ;
15206 }
15207 spin_unlock(&pHddCtx->schedScan_lock);
15208
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015209 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15210
15211 if (0 > ret)
15212 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15213
15214 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15216 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015217}
15218
15219/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015220 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015221 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015222 */
15223static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15224{
15225 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15226 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015227 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015228 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15229 int status = 0;
15230 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15231
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015232 /* The current firmware design does not allow PNO during any
15233 * active sessions. Hence, determine the active sessions
15234 * and return a failure.
15235 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015236 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15237 {
15238 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015239 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015240
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015241 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15242 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15243 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15244 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15245 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015246 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015247 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015248 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015249 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015250 }
15251 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15252 pAdapterNode = pNext;
15253 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015254 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015255}
15256
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015257void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15258{
15259 hdd_adapter_t *pAdapter = callbackContext;
15260 hdd_context_t *pHddCtx;
15261
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015262 ENTER();
15263
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015264 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15265 {
15266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15267 FL("Invalid adapter or adapter has invalid magic"));
15268 return;
15269 }
15270
15271 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15272 if (0 != wlan_hdd_validate_context(pHddCtx))
15273 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015274 return;
15275 }
15276
c_hpothub53c45d2014-08-18 16:53:14 +053015277 if (VOS_STATUS_SUCCESS != status)
15278 {
15279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015280 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015281 pHddCtx->isPnoEnable = FALSE;
15282 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015283
15284 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15285 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015286 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015287}
15288
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015289/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015290 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15291 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015292 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015293static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015294 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15295{
15296 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015297 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015298 hdd_context_t *pHddCtx;
15299 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015300 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015301 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15302 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015303 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15304 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015305 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015306 hdd_config_t *pConfig = NULL;
15307 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015308
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015309 ENTER();
15310
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015311 if (NULL == pAdapter)
15312 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015314 "%s: HDD adapter is Null", __func__);
15315 return -ENODEV;
15316 }
15317
15318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015319 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015320
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015321 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015322 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015323 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015324 }
15325
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015326 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015327 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15328 if (NULL == hHal)
15329 {
15330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15331 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015332 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015333 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15335 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15336 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015337 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015338 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015339 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015340 {
15341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15342 "%s: aborting the existing scan is unsuccessfull", __func__);
15343 return -EBUSY;
15344 }
15345
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015346 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015347 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015349 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015350 return -EBUSY;
15351 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015352
c_hpothu37f21312014-04-09 21:49:54 +053015353 if (TRUE == pHddCtx->isPnoEnable)
15354 {
15355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15356 FL("already PNO is enabled"));
15357 return -EBUSY;
15358 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015359
15360 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15361 {
15362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15363 "%s: abort ROC failed ", __func__);
15364 return -EBUSY;
15365 }
15366
c_hpothu37f21312014-04-09 21:49:54 +053015367 pHddCtx->isPnoEnable = TRUE;
15368
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015369 pnoRequest.enable = 1; /*Enable PNO */
15370 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015371
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015372 if (( !pnoRequest.ucNetworksCount ) ||
15373 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015374 {
15375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015376 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015377 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015378 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015379 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015380 goto error;
15381 }
15382
15383 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15384 {
15385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015386 "%s: Incorrect number of channels %d",
15387 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015388 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015389 goto error;
15390 }
15391
15392 /* Framework provides one set of channels(all)
15393 * common for all saved profile */
15394 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15395 channels_allowed, &num_channels_allowed))
15396 {
15397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15398 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015399 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015400 goto error;
15401 }
15402 /* Checking each channel against allowed channel list */
15403 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015404 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015405 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015406 char chList [(request->n_channels*5)+1];
15407 int len;
15408 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015409 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015410 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015411 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015412 if (request->channels[i]->hw_value == channels_allowed[indx])
15413 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015414 if ((!pConfig->enableDFSPnoChnlScan) &&
15415 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15416 {
15417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15418 "%s : Dropping DFS channel : %d",
15419 __func__,channels_allowed[indx]);
15420 num_ignore_dfs_ch++;
15421 break;
15422 }
15423
Nirav Shah80830bf2013-12-31 16:35:12 +053015424 valid_ch[num_ch++] = request->channels[i]->hw_value;
15425 len += snprintf(chList+len, 5, "%d ",
15426 request->channels[i]->hw_value);
15427 break ;
15428 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015429 }
15430 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015431 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015432
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015433 /*If all channels are DFS and dropped, then ignore the PNO request*/
15434 if (num_ignore_dfs_ch == request->n_channels)
15435 {
15436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15437 "%s : All requested channels are DFS channels", __func__);
15438 ret = -EINVAL;
15439 goto error;
15440 }
15441 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015442
15443 pnoRequest.aNetworks =
15444 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15445 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015446 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015447 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15448 FL("failed to allocate memory aNetworks %u"),
15449 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15450 goto error;
15451 }
15452 vos_mem_zero(pnoRequest.aNetworks,
15453 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15454
15455 /* Filling per profile params */
15456 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15457 {
15458 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015459 request->match_sets[i].ssid.ssid_len;
15460
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015461 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15462 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015463 {
15464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015465 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015466 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015467 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015468 goto error;
15469 }
15470
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015471 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015472 request->match_sets[i].ssid.ssid,
15473 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15475 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015476 i, pnoRequest.aNetworks[i].ssId.ssId);
15477 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15478 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15479 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015480
15481 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015482 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15483 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015484
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015485 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015486 }
15487
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015488 for (i = 0; i < request->n_ssids; i++)
15489 {
15490 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015491 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015492 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015493 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015494 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015495 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015496 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015497 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015498 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015499 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015500 break;
15501 }
15502 j++;
15503 }
15504 }
15505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15506 "Number of hidden networks being Configured = %d",
15507 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015509 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015510
15511 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15512 if (pnoRequest.p24GProbeTemplate == NULL)
15513 {
15514 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15515 FL("failed to allocate memory p24GProbeTemplate %u"),
15516 SIR_PNO_MAX_PB_REQ_SIZE);
15517 goto error;
15518 }
15519
15520 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15521 if (pnoRequest.p5GProbeTemplate == NULL)
15522 {
15523 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15524 FL("failed to allocate memory p5GProbeTemplate %u"),
15525 SIR_PNO_MAX_PB_REQ_SIZE);
15526 goto error;
15527 }
15528
15529 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15530 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15531
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015532 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15533 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015534 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015535 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15536 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15537 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015538
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015539 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15540 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15541 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015542 }
15543
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015544 /* Driver gets only one time interval which is hardcoded in
15545 * supplicant for 10000ms. Taking power consumption into account 6 timers
15546 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15547 * 80,160,320 secs. And number of scan cycle for each timer
15548 * is configurable through INI param gPNOScanTimerRepeatValue.
15549 * If it is set to 0 only one timer will be used and PNO scan cycle
15550 * will be repeated after each interval specified by supplicant
15551 * till PNO is disabled.
15552 */
15553 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015554 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015555 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015556 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015557 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15558
15559 tempInterval = (request->interval)/1000;
15560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15561 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15562 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015563 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015564 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015565 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015566 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015567 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015568 tempInterval *= 2;
15569 }
15570 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015571 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015572
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015573 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015574
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015575 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015576 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15577 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015578 pAdapter->pno_req_status = 0;
15579
Nirav Shah80830bf2013-12-31 16:35:12 +053015580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15581 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015582 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15583 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015584
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015585 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015586 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015587 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15588 if (eHAL_STATUS_SUCCESS != status)
15589 {
15590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015591 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015592 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015593 goto error;
15594 }
15595
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015596 ret = wait_for_completion_timeout(
15597 &pAdapter->pno_comp_var,
15598 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15599 if (0 >= ret)
15600 {
15601 // Did not receive the response for PNO enable in time.
15602 // Assuming the PNO enable was success.
15603 // Returning error from here, because we timeout, results
15604 // in side effect of Wifi (Wifi Setting) not to work.
15605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15606 FL("Timed out waiting for PNO to be Enabled"));
15607 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015608 }
15609
15610 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015611 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015612
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015613error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15615 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015616 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015617 if (pnoRequest.aNetworks)
15618 vos_mem_free(pnoRequest.aNetworks);
15619 if (pnoRequest.p24GProbeTemplate)
15620 vos_mem_free(pnoRequest.p24GProbeTemplate);
15621 if (pnoRequest.p5GProbeTemplate)
15622 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015623
15624 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015625 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015626}
15627
15628/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015629 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15630 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015631 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015632static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15633 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15634{
15635 int ret;
15636
15637 vos_ssr_protect(__func__);
15638 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15639 vos_ssr_unprotect(__func__);
15640
15641 return ret;
15642}
15643
15644/*
15645 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15646 * Function to disable PNO
15647 */
15648static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015649 struct net_device *dev)
15650{
15651 eHalStatus status = eHAL_STATUS_FAILURE;
15652 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15653 hdd_context_t *pHddCtx;
15654 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015655 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015656 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015657
15658 ENTER();
15659
15660 if (NULL == pAdapter)
15661 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015663 "%s: HDD adapter is Null", __func__);
15664 return -ENODEV;
15665 }
15666
15667 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015668
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015669 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015670 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015672 "%s: HDD context is Null", __func__);
15673 return -ENODEV;
15674 }
15675
15676 /* The return 0 is intentional when isLogpInProgress and
15677 * isLoadUnloadInProgress. We did observe a crash due to a return of
15678 * failure in sched_scan_stop , especially for a case where the unload
15679 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15680 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15681 * success. If it returns a failure , then its next invocation due to the
15682 * clean up of the second interface will have the dev pointer corresponding
15683 * to the first one leading to a crash.
15684 */
15685 if (pHddCtx->isLogpInProgress)
15686 {
15687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15688 "%s: LOGP in Progress. Ignore!!!", __func__);
15689 return ret;
15690 }
15691
Mihir Shete18156292014-03-11 15:38:30 +053015692 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015693 {
15694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15695 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15696 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015697 }
15698
15699 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15700 if (NULL == hHal)
15701 {
15702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15703 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015704 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015705 }
15706
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015707 pnoRequest.enable = 0; /* Disable PNO */
15708 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015709
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15711 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15712 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015713 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015714 pAdapter->sessionId,
15715 NULL, pAdapter);
15716 if (eHAL_STATUS_SUCCESS != status)
15717 {
15718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15719 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015720 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015721 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015722 }
c_hpothu37f21312014-04-09 21:49:54 +053015723 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015724
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015725error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015727 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015728
15729 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015730 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015731}
15732
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015733/*
15734 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15735 * NL interface to disable PNO
15736 */
15737static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15738 struct net_device *dev)
15739{
15740 int ret;
15741
15742 vos_ssr_protect(__func__);
15743 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15744 vos_ssr_unprotect(__func__);
15745
15746 return ret;
15747}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015748#endif /*FEATURE_WLAN_SCAN_PNO*/
15749
15750
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015751#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015752#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015753static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15754 struct net_device *dev,
15755 u8 *peer, u8 action_code,
15756 u8 dialog_token,
15757 u16 status_code, u32 peer_capability,
15758 const u8 *buf, size_t len)
15759#else /* TDLS_MGMT_VERSION2 */
15760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15761static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15762 struct net_device *dev,
15763 const u8 *peer, u8 action_code,
15764 u8 dialog_token, u16 status_code,
15765 u32 peer_capability, bool initiator,
15766 const u8 *buf, size_t len)
15767#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15768static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15769 struct net_device *dev,
15770 const u8 *peer, u8 action_code,
15771 u8 dialog_token, u16 status_code,
15772 u32 peer_capability, const u8 *buf,
15773 size_t len)
15774#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15775static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15776 struct net_device *dev,
15777 u8 *peer, u8 action_code,
15778 u8 dialog_token,
15779 u16 status_code, u32 peer_capability,
15780 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015781#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015782static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15783 struct net_device *dev,
15784 u8 *peer, u8 action_code,
15785 u8 dialog_token,
15786 u16 status_code, const u8 *buf,
15787 size_t len)
15788#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015789#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015790{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015791 hdd_adapter_t *pAdapter;
15792 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015793 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015794 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015795 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015796 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015797 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015798#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015799 u32 peer_capability = 0;
15800#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015801 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015802 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015803
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015804 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15805 if (NULL == pAdapter)
15806 {
15807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15808 "%s: Adapter is NULL",__func__);
15809 return -EINVAL;
15810 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15812 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15813 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015814
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015815 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015816 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015819 "Invalid arguments");
15820 return -EINVAL;
15821 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015822
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015823 if (pHddCtx->isLogpInProgress)
15824 {
15825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15826 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015827 wlan_hdd_tdls_set_link_status(pAdapter,
15828 peer,
15829 eTDLS_LINK_IDLE,
15830 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015831 return -EBUSY;
15832 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015833
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015834 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15835 {
15836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15837 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15838 return -EAGAIN;
15839 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015840
Hoonki Lee27511902013-03-14 18:19:06 -070015841 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015842 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015844 "%s: TDLS mode is disabled OR not enabled in FW."
15845 MAC_ADDRESS_STR " action %d declined.",
15846 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015847 return -ENOTSUPP;
15848 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015849
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015850 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15851
15852 if( NULL == pHddStaCtx )
15853 {
15854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15855 "%s: HDD station context NULL ",__func__);
15856 return -EINVAL;
15857 }
15858
15859 /* STA should be connected and authenticated
15860 * before sending any TDLS frames
15861 */
15862 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15863 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15864 {
15865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15866 "STA is not connected or unauthenticated. "
15867 "connState %u, uIsAuthenticated %u",
15868 pHddStaCtx->conn_info.connState,
15869 pHddStaCtx->conn_info.uIsAuthenticated);
15870 return -EAGAIN;
15871 }
15872
Hoonki Lee27511902013-03-14 18:19:06 -070015873 /* other than teardown frame, other mgmt frames are not sent if disabled */
15874 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15875 {
15876 /* if tdls_mode is disabled to respond to peer's request */
15877 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15878 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015880 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015881 " TDLS mode is disabled. action %d declined.",
15882 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015883
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015884 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015885 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015886
15887 if (vos_max_concurrent_connections_reached())
15888 {
15889 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15890 return -EINVAL;
15891 }
Hoonki Lee27511902013-03-14 18:19:06 -070015892 }
15893
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015894 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15895 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015896 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015897 {
15898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015899 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015900 " TDLS setup is ongoing. action %d declined.",
15901 __func__, MAC_ADDR_ARRAY(peer), action_code);
15902 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015903 }
15904 }
15905
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015906 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15907 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015908 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015909 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15910 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015911 {
15912 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15913 we return error code at 'add_station()'. Hence we have this
15914 check again in addtion to add_station().
15915 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015916 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015917 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15919 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015920 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15921 __func__, MAC_ADDR_ARRAY(peer), action_code,
15922 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015923 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015924 }
15925 else
15926 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015927 /* maximum reached. tweak to send error code to peer and return
15928 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015929 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15931 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015932 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15933 __func__, MAC_ADDR_ARRAY(peer), status_code,
15934 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015935 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015936 /* fall through to send setup resp with failure status
15937 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015938 }
15939 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015940 else
15941 {
15942 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015943 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015944 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015945 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015947 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15948 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015949 return -EPERM;
15950 }
15951 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015952 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015953
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015955 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015956 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15957 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015958
Hoonki Leea34dd892013-02-05 22:56:02 -080015959 /*Except teardown responder will not be used so just make 0*/
15960 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015961 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015962 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015963
15964 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015965 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015966
15967 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15968 responder = pTdlsPeer->is_responder;
15969 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015970 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015972 "%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 -070015973 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15974 dialog_token, status_code, len);
15975 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015976 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015977 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015978
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015979 /* For explicit trigger of DIS_REQ come out of BMPS for
15980 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015981 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015982 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15983 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015984 {
15985 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15986 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015988 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015989 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15990 if (status != VOS_STATUS_SUCCESS) {
15991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15992 }
Hoonki Lee14621352013-04-16 17:51:19 -070015993 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015994 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015995 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15997 }
15998 }
Hoonki Lee14621352013-04-16 17:51:19 -070015999 }
16000
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016001 /* make sure doesn't call send_mgmt() while it is pending */
16002 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
16003 {
16004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016005 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016006 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016007 ret = -EBUSY;
16008 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016009 }
16010
16011 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016012 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
16013
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016014 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
16015 pAdapter->sessionId, peer, action_code, dialog_token,
16016 status_code, peer_capability, (tANI_U8 *)buf, len,
16017 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016018
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016019 if (VOS_STATUS_SUCCESS != status)
16020 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16022 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016023 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016024 ret = -EINVAL;
16025 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016026 }
16027
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016028 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
16029 (SIR_MAC_TDLS_DIS_RSP == action_code))
16030 {
16031 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
16032 * So we no need to wait for tdls_mgmt_comp for sending ack status.
16033 */
16034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16035 "%s: tx done for frm %u", __func__, action_code);
16036 return 0;
16037 }
16038
16039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16040 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
16041 WAIT_TIME_TDLS_MGMT);
16042
Hoonki Leed37cbb32013-04-20 00:31:14 -070016043 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
16044 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
16045
16046 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016047 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070016048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016049 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070016050 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016051 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080016052
16053 if (pHddCtx->isLogpInProgress)
16054 {
16055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16056 "%s: LOGP in Progress. Ignore!!!", __func__);
16057 return -EAGAIN;
16058 }
16059
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016060 ret = -EINVAL;
16061 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016062 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016063 else
16064 {
16065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16066 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
16067 __func__, rc, pAdapter->mgmtTxCompletionStatus);
16068 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016069
Gopichand Nakkala05922802013-03-14 12:23:19 -070016070 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070016071 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016072 ret = max_sta_failed;
16073 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070016074 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016075
Hoonki Leea34dd892013-02-05 22:56:02 -080016076 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
16077 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016078 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16080 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016081 }
16082 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
16083 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016084 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16086 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016087 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016088
16089 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016090
16091tx_failed:
16092 /* add_station will be called before sending TDLS_SETUP_REQ and
16093 * TDLS_SETUP_RSP and as part of add_station driver will enable
16094 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
16095 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
16096 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
16097 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
16098 */
16099
16100 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
16101 (SIR_MAC_TDLS_SETUP_RSP == action_code))
16102 wlan_hdd_tdls_check_bmps(pAdapter);
16103 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016104}
16105
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016106#if TDLS_MGMT_VERSION2
16107static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16108 u8 *peer, u8 action_code, u8 dialog_token,
16109 u16 status_code, u32 peer_capability,
16110 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016111#else /* TDLS_MGMT_VERSION2 */
16112#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16113static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16114 struct net_device *dev,
16115 const u8 *peer, u8 action_code,
16116 u8 dialog_token, u16 status_code,
16117 u32 peer_capability, bool initiator,
16118 const u8 *buf, size_t len)
16119#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16120static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16121 struct net_device *dev,
16122 const u8 *peer, u8 action_code,
16123 u8 dialog_token, u16 status_code,
16124 u32 peer_capability, const u8 *buf,
16125 size_t len)
16126#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16127static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16128 struct net_device *dev,
16129 u8 *peer, u8 action_code,
16130 u8 dialog_token,
16131 u16 status_code, u32 peer_capability,
16132 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016133#else
16134static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16135 u8 *peer, u8 action_code, u8 dialog_token,
16136 u16 status_code, const u8 *buf, size_t len)
16137#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016138#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016139{
16140 int ret;
16141
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016142 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016143#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016144 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16145 dialog_token, status_code,
16146 peer_capability, buf, len);
16147#else /* TDLS_MGMT_VERSION2 */
16148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16149 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16150 dialog_token, status_code,
16151 peer_capability, initiator,
16152 buf, len);
16153#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16154 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16155 dialog_token, status_code,
16156 peer_capability, buf, len);
16157#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16158 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16159 dialog_token, status_code,
16160 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016161#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016162 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16163 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016164#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016165#endif
16166 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016167
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016168 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016169}
Atul Mittal115287b2014-07-08 13:26:33 +053016170
16171int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16173 const u8 *peer,
16174#else
Atul Mittal115287b2014-07-08 13:26:33 +053016175 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016176#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016177 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016178 cfg80211_exttdls_callback callback)
16179{
16180
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016181 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016182 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016183 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16185 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16186 __func__, MAC_ADDR_ARRAY(peer));
16187
16188 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16189 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16190
16191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016192 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16193 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16194 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016195 return -ENOTSUPP;
16196 }
16197
16198 /* To cater the requirement of establishing the TDLS link
16199 * irrespective of the data traffic , get an entry of TDLS peer.
16200 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016201 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016202 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16203 if (pTdlsPeer == NULL) {
16204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16205 "%s: peer " MAC_ADDRESS_STR " not existing",
16206 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016207 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016208 return -EINVAL;
16209 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016210 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016211
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016212 /* check FW TDLS Off Channel capability */
16213 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016214 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016215 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016216 {
16217 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16218 pTdlsPeer->peerParams.global_operating_class =
16219 tdls_peer_params->global_operating_class;
16220 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16221 pTdlsPeer->peerParams.min_bandwidth_kbps =
16222 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016223 /* check configured channel is valid, non dfs and
16224 * not current operating channel */
16225 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16226 tdls_peer_params->channel)) &&
16227 (pHddStaCtx) &&
16228 (tdls_peer_params->channel !=
16229 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016230 {
16231 pTdlsPeer->isOffChannelConfigured = TRUE;
16232 }
16233 else
16234 {
16235 pTdlsPeer->isOffChannelConfigured = FALSE;
16236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16237 "%s: Configured Tdls Off Channel is not valid", __func__);
16238
16239 }
16240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016241 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16242 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016243 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016244 pTdlsPeer->isOffChannelConfigured,
16245 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016246 }
16247 else
16248 {
16249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016250 "%s: TDLS off channel FW capability %d, "
16251 "host capab %d or Invalid TDLS Peer Params", __func__,
16252 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16253 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016254 }
16255
Atul Mittal115287b2014-07-08 13:26:33 +053016256 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16257
16258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16259 " %s TDLS Add Force Peer Failed",
16260 __func__);
16261 return -EINVAL;
16262 }
16263 /*EXT TDLS*/
16264
16265 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16267 " %s TDLS set callback Failed",
16268 __func__);
16269 return -EINVAL;
16270 }
16271
16272 return(0);
16273
16274}
16275
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016276int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16278 const u8 *peer
16279#else
16280 u8 *peer
16281#endif
16282)
Atul Mittal115287b2014-07-08 13:26:33 +053016283{
16284
16285 hddTdlsPeer_t *pTdlsPeer;
16286 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16288 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16289 __func__, MAC_ADDR_ARRAY(peer));
16290
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016291 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16293 return -EINVAL;
16294 }
16295
Atul Mittal115287b2014-07-08 13:26:33 +053016296 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16297 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16298
16299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016300 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16301 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16302 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016303 return -ENOTSUPP;
16304 }
16305
16306
16307 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16308
16309 if ( NULL == pTdlsPeer ) {
16310 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016311 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016312 __func__, MAC_ADDR_ARRAY(peer));
16313 return -EINVAL;
16314 }
16315 else {
16316 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16317 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016318 /* if channel switch is configured, reset
16319 the channel for this peer */
16320 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16321 {
16322 pTdlsPeer->peerParams.channel = 0;
16323 pTdlsPeer->isOffChannelConfigured = FALSE;
16324 }
Atul Mittal115287b2014-07-08 13:26:33 +053016325 }
16326
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016327 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016329 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016330 }
Atul Mittal115287b2014-07-08 13:26:33 +053016331
16332 /*EXT TDLS*/
16333
16334 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16335
16336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16337 " %s TDLS set callback Failed",
16338 __func__);
16339 return -EINVAL;
16340 }
16341 return(0);
16342
16343}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016344static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16346 const u8 *peer,
16347#else
16348 u8 *peer,
16349#endif
16350 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016351{
16352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16353 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016354 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016355 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016357 ENTER();
16358
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016359 if (!pAdapter) {
16360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16361 return -EINVAL;
16362 }
16363
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016364 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16365 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16366 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016367 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016368 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016370 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016371 return -EINVAL;
16372 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016373
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016374 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016375 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016376 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016377 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016378 }
16379
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016380
16381 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016382 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016383 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016385 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16386 "Cannot process TDLS commands",
16387 pHddCtx->cfg_ini->fEnableTDLSSupport,
16388 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016389 return -ENOTSUPP;
16390 }
16391
16392 switch (oper) {
16393 case NL80211_TDLS_ENABLE_LINK:
16394 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016395 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016396 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016397 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016398 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016399 tANI_U16 numCurrTdlsPeers = 0;
16400 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016401 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016402
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16404 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16405 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016406 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016407 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016408 if ( NULL == pTdlsPeer ) {
16409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16410 " (oper %d) not exsting. ignored",
16411 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16412 return -EINVAL;
16413 }
16414
16415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16416 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16417 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16418 "NL80211_TDLS_ENABLE_LINK");
16419
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016420 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16421 {
16422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16423 MAC_ADDRESS_STR " failed",
16424 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16425 return -EINVAL;
16426 }
16427
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016428 /* before starting tdls connection, set tdls
16429 * off channel established status to default value */
16430 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016431 /* TDLS Off Channel, Disable tdls channel switch,
16432 when there are more than one tdls link */
16433 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016434 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016435 {
16436 /* get connected peer and send disable tdls off chan */
16437 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016438 if ((connPeer) &&
16439 (connPeer->isOffChannelSupported == TRUE) &&
16440 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016441 {
16442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16443 "%s: More then one peer connected, Disable "
16444 "TDLS channel switch", __func__);
16445
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016446 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016447 ret = sme_SendTdlsChanSwitchReq(
16448 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016449 pAdapter->sessionId,
16450 connPeer->peerMac,
16451 connPeer->peerParams.channel,
16452 TDLS_OFF_CHANNEL_BW_OFFSET,
16453 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016454 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016455 hddLog(VOS_TRACE_LEVEL_ERROR,
16456 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016457 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016458 }
16459 else
16460 {
16461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16462 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016463 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016464 "isOffChannelConfigured %d",
16465 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016466 (connPeer ? (connPeer->isOffChannelSupported)
16467 : -1),
16468 (connPeer ? (connPeer->isOffChannelConfigured)
16469 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016470 }
16471 }
16472
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016473 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016474 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016475 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016476
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016477 if (0 != wlan_hdd_tdls_get_link_establish_params(
16478 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016479 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016480 return -EINVAL;
16481 }
16482 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016483
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016484 ret = sme_SendTdlsLinkEstablishParams(
16485 WLAN_HDD_GET_HAL_CTX(pAdapter),
16486 pAdapter->sessionId, peer,
16487 &tdlsLinkEstablishParams);
16488 if (ret != VOS_STATUS_SUCCESS) {
16489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16490 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016491 /* Send TDLS peer UAPSD capabilities to the firmware and
16492 * register with the TL on after the response for this operation
16493 * is received .
16494 */
16495 ret = wait_for_completion_interruptible_timeout(
16496 &pAdapter->tdls_link_establish_req_comp,
16497 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16498 if (ret <= 0)
16499 {
16500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016501 FL("Link Establish Request Failed Status %ld"),
16502 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016503 return -EINVAL;
16504 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016505 }
Atul Mittal115287b2014-07-08 13:26:33 +053016506 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16507 eTDLS_LINK_CONNECTED,
16508 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016509 staDesc.ucSTAId = pTdlsPeer->staId;
16510 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016511 ret = WLANTL_UpdateTdlsSTAClient(
16512 pHddCtx->pvosContext,
16513 &staDesc);
16514 if (ret != VOS_STATUS_SUCCESS) {
16515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16516 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016517
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016518 /* Mark TDLS client Authenticated .*/
16519 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16520 pTdlsPeer->staId,
16521 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016522 if (VOS_STATUS_SUCCESS == status)
16523 {
Hoonki Lee14621352013-04-16 17:51:19 -070016524 if (pTdlsPeer->is_responder == 0)
16525 {
16526 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016527 tdlsConnInfo_t *tdlsInfo;
16528
16529 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16530
16531 /* Initialize initiator wait callback */
16532 vos_timer_init(
16533 &pTdlsPeer->initiatorWaitTimeoutTimer,
16534 VOS_TIMER_TYPE_SW,
16535 wlan_hdd_tdls_initiator_wait_cb,
16536 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016537
16538 wlan_hdd_tdls_timer_restart(pAdapter,
16539 &pTdlsPeer->initiatorWaitTimeoutTimer,
16540 WAIT_TIME_TDLS_INITIATOR);
16541 /* suspend initiator TX until it receives direct packet from the
16542 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016543 ret = WLANTL_SuspendDataTx(
16544 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16545 &staId, NULL);
16546 if (ret != VOS_STATUS_SUCCESS) {
16547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16548 }
Hoonki Lee14621352013-04-16 17:51:19 -070016549 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016550
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016551 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016552 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016553 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016554 suppChannelLen =
16555 tdlsLinkEstablishParams.supportedChannelsLen;
16556
16557 if ((suppChannelLen > 0) &&
16558 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16559 {
16560 tANI_U8 suppPeerChannel = 0;
16561 int i = 0;
16562 for (i = 0U; i < suppChannelLen; i++)
16563 {
16564 suppPeerChannel =
16565 tdlsLinkEstablishParams.supportedChannels[i];
16566
16567 pTdlsPeer->isOffChannelSupported = FALSE;
16568 if (suppPeerChannel ==
16569 pTdlsPeer->peerParams.channel)
16570 {
16571 pTdlsPeer->isOffChannelSupported = TRUE;
16572 break;
16573 }
16574 }
16575 }
16576 else
16577 {
16578 pTdlsPeer->isOffChannelSupported = FALSE;
16579 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016580 }
16581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16582 "%s: TDLS channel switch request for channel "
16583 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016584 "%d isOffChannelSupported %d", __func__,
16585 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016586 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016587 suppChannelLen,
16588 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016589
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016590 /* TDLS Off Channel, Enable tdls channel switch,
16591 when their is only one tdls link and it supports */
16592 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16593 if ((numCurrTdlsPeers == 1) &&
16594 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16595 (TRUE == pTdlsPeer->isOffChannelConfigured))
16596 {
16597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16598 "%s: Send TDLS channel switch request for channel %d",
16599 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016600
16601 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016602 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16603 pAdapter->sessionId,
16604 pTdlsPeer->peerMac,
16605 pTdlsPeer->peerParams.channel,
16606 TDLS_OFF_CHANNEL_BW_OFFSET,
16607 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016608 if (ret != VOS_STATUS_SUCCESS) {
16609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16610 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016611 }
16612 else
16613 {
16614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16615 "%s: TDLS channel switch request not sent"
16616 " numCurrTdlsPeers %d "
16617 "isOffChannelSupported %d "
16618 "isOffChannelConfigured %d",
16619 __func__, numCurrTdlsPeers,
16620 pTdlsPeer->isOffChannelSupported,
16621 pTdlsPeer->isOffChannelConfigured);
16622 }
16623
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016624 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016625 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016626
16627 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016628 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16629 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016630 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016631 int ac;
16632 uint8 ucAc[4] = { WLANTL_AC_VO,
16633 WLANTL_AC_VI,
16634 WLANTL_AC_BK,
16635 WLANTL_AC_BE };
16636 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16637 for(ac=0; ac < 4; ac++)
16638 {
16639 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16640 pTdlsPeer->staId, ucAc[ac],
16641 tlTid[ac], tlTid[ac], 0, 0,
16642 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016643 if (status != VOS_STATUS_SUCCESS) {
16644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16645 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016646 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016647 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016648 }
16649
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016650 }
16651 break;
16652 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016653 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016654 tANI_U16 numCurrTdlsPeers = 0;
16655 hddTdlsPeer_t *connPeer = NULL;
16656
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16658 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16659 __func__, MAC_ADDR_ARRAY(peer));
16660
Sunil Dutt41de4e22013-11-14 18:09:02 +053016661 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16662
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016663
Sunil Dutt41de4e22013-11-14 18:09:02 +053016664 if ( NULL == pTdlsPeer ) {
16665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16666 " (oper %d) not exsting. ignored",
16667 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16668 return -EINVAL;
16669 }
16670
16671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16672 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16673 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16674 "NL80211_TDLS_DISABLE_LINK");
16675
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016676 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016677 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016678 long status;
16679
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016680 /* set tdls off channel status to false for this peer */
16681 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016682 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16683 eTDLS_LINK_TEARING,
16684 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16685 eTDLS_LINK_UNSPECIFIED:
16686 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016687 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16688
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016689 status = sme_DeleteTdlsPeerSta(
16690 WLAN_HDD_GET_HAL_CTX(pAdapter),
16691 pAdapter->sessionId, peer );
16692 if (status != VOS_STATUS_SUCCESS) {
16693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16694 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016695
16696 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16697 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016698 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016699 eTDLS_LINK_IDLE,
16700 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016701 if (status <= 0)
16702 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16704 "%s: Del station failed status %ld",
16705 __func__, status);
16706 return -EPERM;
16707 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016708
16709 /* TDLS Off Channel, Enable tdls channel switch,
16710 when their is only one tdls link and it supports */
16711 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16712 if (numCurrTdlsPeers == 1)
16713 {
16714 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16715 if ((connPeer) &&
16716 (connPeer->isOffChannelSupported == TRUE) &&
16717 (connPeer->isOffChannelConfigured == TRUE))
16718 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016719 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016720 status = sme_SendTdlsChanSwitchReq(
16721 WLAN_HDD_GET_HAL_CTX(pAdapter),
16722 pAdapter->sessionId,
16723 connPeer->peerMac,
16724 connPeer->peerParams.channel,
16725 TDLS_OFF_CHANNEL_BW_OFFSET,
16726 TDLS_CHANNEL_SWITCH_ENABLE);
16727 if (status != VOS_STATUS_SUCCESS) {
16728 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16729 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016730 }
16731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16732 "%s: TDLS channel switch "
16733 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016734 "isOffChannelConfigured %d "
16735 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016736 __func__,
16737 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016738 (connPeer ? connPeer->isOffChannelConfigured : -1),
16739 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016740 }
16741 else
16742 {
16743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16744 "%s: TDLS channel switch request not sent "
16745 "numCurrTdlsPeers %d ",
16746 __func__, numCurrTdlsPeers);
16747 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016748 }
16749 else
16750 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16752 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016753 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016754 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016755 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016756 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016757 {
Atul Mittal115287b2014-07-08 13:26:33 +053016758 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016759
Atul Mittal115287b2014-07-08 13:26:33 +053016760 if (0 != status)
16761 {
16762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016763 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016764 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016765 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016766 break;
16767 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016768 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016769 {
Atul Mittal115287b2014-07-08 13:26:33 +053016770 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16771 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016772 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016773 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016774
Atul Mittal115287b2014-07-08 13:26:33 +053016775 if (0 != status)
16776 {
16777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016778 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016779 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016780 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016781 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016782 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016783 case NL80211_TDLS_DISCOVERY_REQ:
16784 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016786 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016787 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016788 return -ENOTSUPP;
16789 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16791 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016792 return -ENOTSUPP;
16793 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016794
16795 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016796 return 0;
16797}
Chilam NG571c65a2013-01-19 12:27:36 +053016798
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016799static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16801 const u8 *peer,
16802#else
16803 u8 *peer,
16804#endif
16805 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016806{
16807 int ret;
16808
16809 vos_ssr_protect(__func__);
16810 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16811 vos_ssr_unprotect(__func__);
16812
16813 return ret;
16814}
16815
Chilam NG571c65a2013-01-19 12:27:36 +053016816int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16817 struct net_device *dev, u8 *peer)
16818{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016819 hddLog(VOS_TRACE_LEVEL_INFO,
16820 "tdls send discover req: "MAC_ADDRESS_STR,
16821 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016822
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016823#if TDLS_MGMT_VERSION2
16824 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16825 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16826#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16828 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16829 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16830#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16831 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16832 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16833#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16834 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16835 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16836#else
Chilam NG571c65a2013-01-19 12:27:36 +053016837 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16838 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016839#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016840#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016841}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016842#endif
16843
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016844#ifdef WLAN_FEATURE_GTK_OFFLOAD
16845/*
16846 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16847 * Callback rountine called upon receiving response for
16848 * get offload info
16849 */
16850void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16851 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16852{
16853
16854 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016855 tANI_U8 tempReplayCounter[8];
16856 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016857
16858 ENTER();
16859
16860 if (NULL == pAdapter)
16861 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016863 "%s: HDD adapter is Null", __func__);
16864 return ;
16865 }
16866
16867 if (NULL == pGtkOffloadGetInfoRsp)
16868 {
16869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16870 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16871 return ;
16872 }
16873
16874 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16875 {
16876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16877 "%s: wlan Failed to get replay counter value",
16878 __func__);
16879 return ;
16880 }
16881
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016882 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16883 /* Update replay counter */
16884 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16885 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16886
16887 {
16888 /* changing from little to big endian since supplicant
16889 * works on big endian format
16890 */
16891 int i;
16892 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16893
16894 for (i = 0; i < 8; i++)
16895 {
16896 tempReplayCounter[7-i] = (tANI_U8)p[i];
16897 }
16898 }
16899
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016900 /* Update replay counter to NL */
16901 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016902 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016903}
16904
16905/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016906 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016907 * This function is used to offload GTK rekeying job to the firmware.
16908 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016909int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016910 struct cfg80211_gtk_rekey_data *data)
16911{
16912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16913 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16914 hdd_station_ctx_t *pHddStaCtx;
16915 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016916 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016917 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016918 eHalStatus status = eHAL_STATUS_FAILURE;
16919
16920 ENTER();
16921
16922 if (NULL == pAdapter)
16923 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016925 "%s: HDD adapter is Null", __func__);
16926 return -ENODEV;
16927 }
16928
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016929 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16930 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16931 pAdapter->sessionId, pAdapter->device_mode));
16932
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016933 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016934 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016935 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016936 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016937 }
16938
16939 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16940 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16941 if (NULL == hHal)
16942 {
16943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16944 "%s: HAL context is Null!!!", __func__);
16945 return -EAGAIN;
16946 }
16947
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016948 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16949 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16950 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16951 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016952 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016953 {
16954 /* changing from big to little endian since driver
16955 * works on little endian format
16956 */
16957 tANI_U8 *p =
16958 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16959 int i;
16960
16961 for (i = 0; i < 8; i++)
16962 {
16963 p[7-i] = data->replay_ctr[i];
16964 }
16965 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016966
16967 if (TRUE == pHddCtx->hdd_wlan_suspended)
16968 {
16969 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016970 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16971 sizeof (tSirGtkOffloadParams));
16972 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016973 pAdapter->sessionId);
16974
16975 if (eHAL_STATUS_SUCCESS != status)
16976 {
16977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16978 "%s: sme_SetGTKOffload failed, returned %d",
16979 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016980
16981 /* Need to clear any trace of key value in the memory.
16982 * Thus zero out the memory even though it is local
16983 * variable.
16984 */
16985 vos_mem_zero(&hddGtkOffloadReqParams,
16986 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016987 return status;
16988 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16990 "%s: sme_SetGTKOffload successfull", __func__);
16991 }
16992 else
16993 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16995 "%s: wlan not suspended GTKOffload request is stored",
16996 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016997 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016998
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016999 /* Need to clear any trace of key value in the memory.
17000 * Thus zero out the memory even though it is local
17001 * variable.
17002 */
17003 vos_mem_zero(&hddGtkOffloadReqParams,
17004 sizeof(hddGtkOffloadReqParams));
17005
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017006 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017007 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017008}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017009
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017010int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
17011 struct cfg80211_gtk_rekey_data *data)
17012{
17013 int ret;
17014
17015 vos_ssr_protect(__func__);
17016 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
17017 vos_ssr_unprotect(__func__);
17018
17019 return ret;
17020}
17021#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017022/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017023 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017024 * This function is used to set access control policy
17025 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017026static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17027 struct net_device *dev,
17028 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017029{
17030 int i;
17031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17032 hdd_hostapd_state_t *pHostapdState;
17033 tsap_Config_t *pConfig;
17034 v_CONTEXT_t pVosContext = NULL;
17035 hdd_context_t *pHddCtx;
17036 int status;
17037
17038 ENTER();
17039
17040 if (NULL == pAdapter)
17041 {
17042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17043 "%s: HDD adapter is Null", __func__);
17044 return -ENODEV;
17045 }
17046
17047 if (NULL == params)
17048 {
17049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17050 "%s: params is Null", __func__);
17051 return -EINVAL;
17052 }
17053
17054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17055 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017056 if (0 != status)
17057 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017058 return status;
17059 }
17060
17061 pVosContext = pHddCtx->pvosContext;
17062 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
17063
17064 if (NULL == pHostapdState)
17065 {
17066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17067 "%s: pHostapdState is Null", __func__);
17068 return -EINVAL;
17069 }
17070
17071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
17072 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17074 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
17075 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017076
17077 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
17078 {
17079 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
17080
17081 /* default value */
17082 pConfig->num_accept_mac = 0;
17083 pConfig->num_deny_mac = 0;
17084
17085 /**
17086 * access control policy
17087 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
17088 * listed in hostapd.deny file.
17089 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
17090 * listed in hostapd.accept file.
17091 */
17092 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
17093 {
17094 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
17095 }
17096 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
17097 {
17098 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
17099 }
17100 else
17101 {
17102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17103 "%s:Acl Policy : %d is not supported",
17104 __func__, params->acl_policy);
17105 return -ENOTSUPP;
17106 }
17107
17108 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
17109 {
17110 pConfig->num_accept_mac = params->n_acl_entries;
17111 for (i = 0; i < params->n_acl_entries; i++)
17112 {
17113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17114 "** Add ACL MAC entry %i in WhiletList :"
17115 MAC_ADDRESS_STR, i,
17116 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17117
17118 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17119 sizeof(qcmacaddr));
17120 }
17121 }
17122 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17123 {
17124 pConfig->num_deny_mac = params->n_acl_entries;
17125 for (i = 0; i < params->n_acl_entries; i++)
17126 {
17127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17128 "** Add ACL MAC entry %i in BlackList :"
17129 MAC_ADDRESS_STR, i,
17130 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17131
17132 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17133 sizeof(qcmacaddr));
17134 }
17135 }
17136
17137 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17138 {
17139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17140 "%s: SAP Set Mac Acl fail", __func__);
17141 return -EINVAL;
17142 }
17143 }
17144 else
17145 {
17146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017147 "%s: Invalid device_mode = %s (%d)",
17148 __func__, hdd_device_modetoString(pAdapter->device_mode),
17149 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017150 return -EINVAL;
17151 }
17152
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017153 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017154 return 0;
17155}
17156
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017157static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17158 struct net_device *dev,
17159 const struct cfg80211_acl_data *params)
17160{
17161 int ret;
17162 vos_ssr_protect(__func__);
17163 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17164 vos_ssr_unprotect(__func__);
17165
17166 return ret;
17167}
17168
Leo Chang9056f462013-08-01 19:21:11 -070017169#ifdef WLAN_NL80211_TESTMODE
17170#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017171void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017172(
17173 void *pAdapter,
17174 void *indCont
17175)
17176{
Leo Changd9df8aa2013-09-26 13:32:26 -070017177 tSirLPHBInd *lphbInd;
17178 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017179 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017180
17181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017182 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017183
c_hpothu73f35e62014-04-18 13:40:08 +053017184 if (pAdapter == NULL)
17185 {
17186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17187 "%s: pAdapter is NULL\n",__func__);
17188 return;
17189 }
17190
Leo Chang9056f462013-08-01 19:21:11 -070017191 if (NULL == indCont)
17192 {
17193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017194 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017195 return;
17196 }
17197
c_hpothu73f35e62014-04-18 13:40:08 +053017198 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017199 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017200 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017201 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017202 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017203 GFP_ATOMIC);
17204 if (!skb)
17205 {
17206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17207 "LPHB timeout, NL buffer alloc fail");
17208 return;
17209 }
17210
Leo Changac3ba772013-10-07 09:47:04 -070017211 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017212 {
17213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17214 "WLAN_HDD_TM_ATTR_CMD put fail");
17215 goto nla_put_failure;
17216 }
Leo Changac3ba772013-10-07 09:47:04 -070017217 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017218 {
17219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17220 "WLAN_HDD_TM_ATTR_TYPE put fail");
17221 goto nla_put_failure;
17222 }
Leo Changac3ba772013-10-07 09:47:04 -070017223 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017224 sizeof(tSirLPHBInd), lphbInd))
17225 {
17226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17227 "WLAN_HDD_TM_ATTR_DATA put fail");
17228 goto nla_put_failure;
17229 }
Leo Chang9056f462013-08-01 19:21:11 -070017230 cfg80211_testmode_event(skb, GFP_ATOMIC);
17231 return;
17232
17233nla_put_failure:
17234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17235 "NLA Put fail");
17236 kfree_skb(skb);
17237
17238 return;
17239}
17240#endif /* FEATURE_WLAN_LPHB */
17241
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017242static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017243{
17244 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17245 int err = 0;
17246#ifdef FEATURE_WLAN_LPHB
17247 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017248 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017249
17250 ENTER();
17251
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017252 err = wlan_hdd_validate_context(pHddCtx);
17253 if (0 != err)
17254 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017255 return err;
17256 }
Leo Chang9056f462013-08-01 19:21:11 -070017257#endif /* FEATURE_WLAN_LPHB */
17258
17259 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17260 if (err)
17261 {
17262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17263 "%s Testmode INV ATTR", __func__);
17264 return err;
17265 }
17266
17267 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17268 {
17269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17270 "%s Testmode INV CMD", __func__);
17271 return -EINVAL;
17272 }
17273
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017274 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17275 TRACE_CODE_HDD_CFG80211_TESTMODE,
17276 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017277 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17278 {
17279#ifdef FEATURE_WLAN_LPHB
17280 /* Low Power Heartbeat configuration request */
17281 case WLAN_HDD_TM_CMD_WLAN_HB:
17282 {
17283 int buf_len;
17284 void *buf;
17285 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017286 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017287
17288 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17289 {
17290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17291 "%s Testmode INV DATA", __func__);
17292 return -EINVAL;
17293 }
17294
17295 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17296 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017297
17298 hb_params_temp =(tSirLPHBReq *)buf;
17299 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17300 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17301 return -EINVAL;
17302
Leo Chang9056f462013-08-01 19:21:11 -070017303 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17304 if (NULL == hb_params)
17305 {
17306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17307 "%s Request Buffer Alloc Fail", __func__);
17308 return -EINVAL;
17309 }
17310
17311 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017312 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17313 hb_params,
17314 wlan_hdd_cfg80211_lphb_ind_handler);
17315 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017316 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17318 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017319 vos_mem_free(hb_params);
17320 }
Leo Chang9056f462013-08-01 19:21:11 -070017321 return 0;
17322 }
17323#endif /* FEATURE_WLAN_LPHB */
17324 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17326 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017327 return -EOPNOTSUPP;
17328 }
17329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017330 EXIT();
17331 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017332}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017333
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017334static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17336 struct wireless_dev *wdev,
17337#endif
17338 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017339{
17340 int ret;
17341
17342 vos_ssr_protect(__func__);
17343 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17344 vos_ssr_unprotect(__func__);
17345
17346 return ret;
17347}
Leo Chang9056f462013-08-01 19:21:11 -070017348#endif /* CONFIG_NL80211_TESTMODE */
17349
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017350static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017351 struct net_device *dev,
17352 int idx, struct survey_info *survey)
17353{
17354 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17355 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017356 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017357 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017358 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017359 v_S7_t snr,rssi;
17360 int status, i, j, filled = 0;
17361
17362 ENTER();
17363
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017364 if (NULL == pAdapter)
17365 {
17366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17367 "%s: HDD adapter is Null", __func__);
17368 return -ENODEV;
17369 }
17370
17371 if (NULL == wiphy)
17372 {
17373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17374 "%s: wiphy is Null", __func__);
17375 return -ENODEV;
17376 }
17377
17378 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17379 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017380 if (0 != status)
17381 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017382 return status;
17383 }
17384
Mihir Sheted9072e02013-08-21 17:02:29 +053017385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17386
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017387 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017388 0 != pAdapter->survey_idx ||
17389 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017390 {
17391 /* The survey dump ops when implemented completely is expected to
17392 * return a survey of all channels and the ops is called by the
17393 * kernel with incremental values of the argument 'idx' till it
17394 * returns -ENONET. But we can only support the survey for the
17395 * operating channel for now. survey_idx is used to track
17396 * that the ops is called only once and then return -ENONET for
17397 * the next iteration
17398 */
17399 pAdapter->survey_idx = 0;
17400 return -ENONET;
17401 }
17402
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017403 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17404 {
17405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17406 "%s: Roaming in progress, hence return ", __func__);
17407 return -ENONET;
17408 }
17409
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017410 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17411
17412 wlan_hdd_get_snr(pAdapter, &snr);
17413 wlan_hdd_get_rssi(pAdapter, &rssi);
17414
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017415 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17416 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17417 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017418 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17419 hdd_wlan_get_freq(channel, &freq);
17420
17421
17422 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17423 {
17424 if (NULL == wiphy->bands[i])
17425 {
17426 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17427 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17428 continue;
17429 }
17430
17431 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17432 {
17433 struct ieee80211_supported_band *band = wiphy->bands[i];
17434
17435 if (band->channels[j].center_freq == (v_U16_t)freq)
17436 {
17437 survey->channel = &band->channels[j];
17438 /* The Rx BDs contain SNR values in dB for the received frames
17439 * while the supplicant expects noise. So we calculate and
17440 * return the value of noise (dBm)
17441 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17442 */
17443 survey->noise = rssi - snr;
17444 survey->filled = SURVEY_INFO_NOISE_DBM;
17445 filled = 1;
17446 }
17447 }
17448 }
17449
17450 if (filled)
17451 pAdapter->survey_idx = 1;
17452 else
17453 {
17454 pAdapter->survey_idx = 0;
17455 return -ENONET;
17456 }
17457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017458 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017459 return 0;
17460}
17461
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017462static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17463 struct net_device *dev,
17464 int idx, struct survey_info *survey)
17465{
17466 int ret;
17467
17468 vos_ssr_protect(__func__);
17469 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17470 vos_ssr_unprotect(__func__);
17471
17472 return ret;
17473}
17474
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017475/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017476 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017477 * this is called when cfg80211 driver resume
17478 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17479 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017480int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017481{
17482 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17483 hdd_adapter_t *pAdapter;
17484 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17485 VOS_STATUS status = VOS_STATUS_SUCCESS;
17486
17487 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017488
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017489 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017490 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017491 return 0;
17492 }
17493
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017494 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17495 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017496 spin_lock(&pHddCtx->schedScan_lock);
17497 pHddCtx->isWiphySuspended = FALSE;
17498 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17499 {
17500 spin_unlock(&pHddCtx->schedScan_lock);
17501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17502 "%s: Return resume is not due to PNO indication", __func__);
17503 return 0;
17504 }
17505 // Reset flag to avoid updatating cfg80211 data old results again
17506 pHddCtx->isSchedScanUpdatePending = FALSE;
17507 spin_unlock(&pHddCtx->schedScan_lock);
17508
17509 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17510
17511 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17512 {
17513 pAdapter = pAdapterNode->pAdapter;
17514 if ( (NULL != pAdapter) &&
17515 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17516 {
17517 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017518 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17520 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017521 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017522 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017523 {
17524 /* Acquire wakelock to handle the case where APP's tries to
17525 * suspend immediately after updating the scan results. Whis
17526 * results in app's is in suspended state and not able to
17527 * process the connect request to AP
17528 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017529 hdd_prevent_suspend_timeout(2000,
17530 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017531 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017532 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017533
17534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17535 "%s : cfg80211 scan result database updated", __func__);
17536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017537 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017538 return 0;
17539
17540 }
17541 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17542 pAdapterNode = pNext;
17543 }
17544
17545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17546 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017547 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017548 return 0;
17549}
17550
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017551int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17552{
17553 int ret;
17554
17555 vos_ssr_protect(__func__);
17556 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17557 vos_ssr_unprotect(__func__);
17558
17559 return ret;
17560}
17561
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017562/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017563 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017564 * this is called when cfg80211 driver suspends
17565 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017566int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017567 struct cfg80211_wowlan *wow)
17568{
17569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017570 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017571
17572 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017573
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017574 ret = wlan_hdd_validate_context(pHddCtx);
17575 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017576 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017577 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017578 }
17579
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017580
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17582 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17583 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017584 pHddCtx->isWiphySuspended = TRUE;
17585
17586 EXIT();
17587
17588 return 0;
17589}
17590
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017591int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17592 struct cfg80211_wowlan *wow)
17593{
17594 int ret;
17595
17596 vos_ssr_protect(__func__);
17597 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17598 vos_ssr_unprotect(__func__);
17599
17600 return ret;
17601}
Jeff Johnson295189b2012-06-20 16:38:30 -070017602/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017603static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017604{
17605 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17606 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17607 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17608 .change_station = wlan_hdd_change_station,
17609#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17610 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17611 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17612 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017613#else
17614 .start_ap = wlan_hdd_cfg80211_start_ap,
17615 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17616 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017617#endif
17618 .change_bss = wlan_hdd_cfg80211_change_bss,
17619 .add_key = wlan_hdd_cfg80211_add_key,
17620 .get_key = wlan_hdd_cfg80211_get_key,
17621 .del_key = wlan_hdd_cfg80211_del_key,
17622 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017624 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017626 .scan = wlan_hdd_cfg80211_scan,
17627 .connect = wlan_hdd_cfg80211_connect,
17628 .disconnect = wlan_hdd_cfg80211_disconnect,
17629 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17630 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17631 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17632 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17633 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17635 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017636 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017637#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17638 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17639 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17640 .set_txq_params = wlan_hdd_set_txq_params,
17641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017642 .get_station = wlan_hdd_cfg80211_get_station,
17643 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17644 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017645 .add_station = wlan_hdd_cfg80211_add_station,
17646#ifdef FEATURE_WLAN_LFR
17647 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17648 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17649 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17650#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017651#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17652 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17653#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017654#ifdef FEATURE_WLAN_TDLS
17655 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17656 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17657#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017658#ifdef WLAN_FEATURE_GTK_OFFLOAD
17659 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17660#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017661#ifdef FEATURE_WLAN_SCAN_PNO
17662 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17663 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17664#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017665 .resume = wlan_hdd_cfg80211_resume_wlan,
17666 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017667 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017668#ifdef WLAN_NL80211_TESTMODE
17669 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17670#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017671 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017672};
17673