blob: eac14c7c90202848b82a4773620233698eeb5876 [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) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305825 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5826 !vos_isPktStatsEnabled()))
5827
Sushant Kaushik8e644982015-09-23 12:18:54 +05305828 {
5829 hddLog(LOGE, FL("per pkt stats not enabled"));
5830 return -EINVAL;
5831 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832
Sushant Kaushik33200572015-08-05 16:46:20 +05305833 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305834 return 0;
5835}
5836
5837/**
5838 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5839 * or disable the collection of packet statistics from the firmware
5840 * @wiphy: WIPHY structure pointer
5841 * @wdev: Wireless device structure pointer
5842 * @data: Pointer to the data received
5843 * @data_len: Length of the data received
5844 *
5845 * This function is used to enable or disable the collection of packet
5846 * statistics from the firmware
5847 *
5848 * Return: 0 on success and errno on failure
5849 */
5850static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5851 struct wireless_dev *wdev,
5852 const void *data,
5853 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305854{
5855 int ret = 0;
5856
5857 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305858
5859 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5860 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305861 vos_ssr_unprotect(__func__);
5862
5863 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305864}
5865
5866
Agarwal Ashish738843c2014-09-25 12:27:56 +05305867static const struct nla_policy
5868wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5869 +1] =
5870{
5871 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5872};
5873
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305874static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305875 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305876 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305877 int data_len)
5878{
5879 struct net_device *dev = wdev->netdev;
5880 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5881 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5882 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5883 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5884 eHalStatus status;
5885 u32 dfsFlag = 0;
5886
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305887 ENTER();
5888
Agarwal Ashish738843c2014-09-25 12:27:56 +05305889 status = wlan_hdd_validate_context(pHddCtx);
5890 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305891 return -EINVAL;
5892 }
5893 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5894 data, data_len,
5895 wlan_hdd_set_no_dfs_flag_config_policy)) {
5896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5897 return -EINVAL;
5898 }
5899
5900 /* Parse and fetch required bandwidth kbps */
5901 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5903 return -EINVAL;
5904 }
5905
5906 dfsFlag = nla_get_u32(
5907 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5908 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5909 dfsFlag);
5910
5911 pHddCtx->disable_dfs_flag = dfsFlag;
5912
5913 sme_disable_dfs_channel(hHal, dfsFlag);
5914 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305915
5916 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305917 return 0;
5918}
Atul Mittal115287b2014-07-08 13:26:33 +05305919
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305920static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5921 struct wireless_dev *wdev,
5922 const void *data,
5923 int data_len)
5924{
5925 int ret = 0;
5926
5927 vos_ssr_protect(__func__);
5928 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5929 vos_ssr_unprotect(__func__);
5930
5931 return ret;
5932
5933}
5934
Mukul Sharma2a271632014-10-13 14:59:01 +05305935const struct
5936nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5937{
5938 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5939 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5940};
5941
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305942static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305943 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305944{
5945
5946 u8 bssid[6] = {0};
5947 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5948 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5949 eHalStatus status = eHAL_STATUS_SUCCESS;
5950 v_U32_t isFwrRoamEnabled = FALSE;
5951 int ret;
5952
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305953 ENTER();
5954
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305955 ret = wlan_hdd_validate_context(pHddCtx);
5956 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305957 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305958 }
5959
5960 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5961 data, data_len,
5962 qca_wlan_vendor_attr);
5963 if (ret){
5964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5965 return -EINVAL;
5966 }
5967
5968 /* Parse and fetch Enable flag */
5969 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5971 return -EINVAL;
5972 }
5973
5974 isFwrRoamEnabled = nla_get_u32(
5975 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5976
5977 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5978
5979 /* Parse and fetch bssid */
5980 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5982 return -EINVAL;
5983 }
5984
5985 memcpy(bssid, nla_data(
5986 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5987 sizeof(bssid));
5988 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5989
5990 //Update roaming
5991 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305992 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305993 return status;
5994}
5995
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305996static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5997 struct wireless_dev *wdev, const void *data, int data_len)
5998{
5999 int ret = 0;
6000
6001 vos_ssr_protect(__func__);
6002 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6003 vos_ssr_unprotect(__func__);
6004
6005 return ret;
6006}
6007
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306008/**
6009 * __wlan_hdd_cfg80211_setband() - set band
6010 * @wiphy: Pointer to wireless phy
6011 * @wdev: Pointer to wireless device
6012 * @data: Pointer to data
6013 * @data_len: Data length
6014 *
6015 * Return: 0 on success, negative errno on failure
6016 */
6017static int
6018__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6019 struct wireless_dev *wdev,
6020 const void *data,
6021 int data_len)
6022{
6023 struct net_device *dev = wdev->netdev;
6024 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6025 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6026 int ret;
6027 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6028 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6029
6030 ENTER();
6031
6032 ret = wlan_hdd_validate_context(hdd_ctx);
6033 if (0 != ret) {
6034 hddLog(LOGE, FL("HDD context is not valid"));
6035 return ret;
6036 }
6037
6038 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6039 policy)) {
6040 hddLog(LOGE, FL("Invalid ATTR"));
6041 return -EINVAL;
6042 }
6043
6044 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6045 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6046 return -EINVAL;
6047 }
6048
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306049 hdd_ctx->isSetBandByNL = TRUE;
6050 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306051 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306052 hdd_ctx->isSetBandByNL = FALSE;
6053
6054 EXIT();
6055 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306056}
6057
6058/**
6059 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6060 * @wiphy: wiphy structure pointer
6061 * @wdev: Wireless device structure pointer
6062 * @data: Pointer to the data received
6063 * @data_len: Length of @data
6064 *
6065 * Return: 0 on success; errno on failure
6066 */
6067static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6068 struct wireless_dev *wdev,
6069 const void *data,
6070 int data_len)
6071{
6072 int ret = 0;
6073
6074 vos_ssr_protect(__func__);
6075 ret = __wlan_hdd_cfg80211_setband(wiphy,
6076 wdev, data, data_len);
6077 vos_ssr_unprotect(__func__);
6078
6079 return ret;
6080}
6081
Sunil Duttc69bccb2014-05-26 21:30:20 +05306082const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6083{
Mukul Sharma2a271632014-10-13 14:59:01 +05306084 {
6085 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6086 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6087 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6088 WIPHY_VENDOR_CMD_NEED_NETDEV |
6089 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306090 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306091 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306092
6093 {
6094 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6095 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6096 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6097 WIPHY_VENDOR_CMD_NEED_NETDEV |
6098 WIPHY_VENDOR_CMD_NEED_RUNNING,
6099 .doit = wlan_hdd_cfg80211_nan_request
6100 },
6101
Sunil Duttc69bccb2014-05-26 21:30:20 +05306102#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6103 {
6104 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6105 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6106 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6107 WIPHY_VENDOR_CMD_NEED_NETDEV |
6108 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306109 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306110 },
6111
6112 {
6113 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6114 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6115 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6116 WIPHY_VENDOR_CMD_NEED_NETDEV |
6117 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306118 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306119 },
6120
6121 {
6122 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6123 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6124 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6125 WIPHY_VENDOR_CMD_NEED_NETDEV |
6126 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306127 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306128 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306129#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306130#ifdef WLAN_FEATURE_EXTSCAN
6131 {
6132 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6133 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6134 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6135 WIPHY_VENDOR_CMD_NEED_NETDEV |
6136 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306137 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306138 },
6139 {
6140 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6141 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6142 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6143 WIPHY_VENDOR_CMD_NEED_NETDEV |
6144 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306145 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306146 },
6147 {
6148 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6149 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6150 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6151 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306152 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306153 },
6154 {
6155 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6156 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6157 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6158 WIPHY_VENDOR_CMD_NEED_NETDEV |
6159 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306160 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306161 },
6162 {
6163 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6164 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6165 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6166 WIPHY_VENDOR_CMD_NEED_NETDEV |
6167 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306168 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306169 },
6170 {
6171 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6172 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6173 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6174 WIPHY_VENDOR_CMD_NEED_NETDEV |
6175 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306176 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306177 },
6178 {
6179 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6180 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6181 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6182 WIPHY_VENDOR_CMD_NEED_NETDEV |
6183 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306184 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306185 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306186 {
6187 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6188 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6189 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6190 WIPHY_VENDOR_CMD_NEED_NETDEV |
6191 WIPHY_VENDOR_CMD_NEED_RUNNING,
6192 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6193 },
6194 {
6195 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6196 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6197 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6198 WIPHY_VENDOR_CMD_NEED_NETDEV |
6199 WIPHY_VENDOR_CMD_NEED_RUNNING,
6200 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6201 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306202#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306203/*EXT TDLS*/
6204 {
6205 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6206 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6207 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6208 WIPHY_VENDOR_CMD_NEED_NETDEV |
6209 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306210 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306211 },
6212 {
6213 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6214 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6215 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6216 WIPHY_VENDOR_CMD_NEED_NETDEV |
6217 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306218 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306219 },
6220 {
6221 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6222 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6223 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6224 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306225 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306226 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306227 {
6228 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6229 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6230 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6231 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306232 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306233 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306234 {
6235 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6236 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6237 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6238 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306239 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306240 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306241 {
6242 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6243 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6244 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6245 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306246 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306247 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306248 {
6249 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6250 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6251 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6252 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306253 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306254 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306255 {
6256 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306257 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6258 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6259 WIPHY_VENDOR_CMD_NEED_NETDEV |
6260 WIPHY_VENDOR_CMD_NEED_RUNNING,
6261 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6262 },
6263 {
6264 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306265 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6266 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6267 WIPHY_VENDOR_CMD_NEED_NETDEV |
6268 WIPHY_VENDOR_CMD_NEED_RUNNING,
6269 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05306270 },
6271 {
6272 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6273 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
6274 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6275 WIPHY_VENDOR_CMD_NEED_NETDEV,
6276 .doit = wlan_hdd_cfg80211_wifi_logger_start
6277 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306278};
6279
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006280/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306281static const
6282struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006283{
6284#ifdef FEATURE_WLAN_CH_AVOID
6285 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306286 .vendor_id = QCA_NL80211_VENDOR_ID,
6287 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006288 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306289#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6290#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6291 {
6292 /* Index = 1*/
6293 .vendor_id = QCA_NL80211_VENDOR_ID,
6294 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6295 },
6296 {
6297 /* Index = 2*/
6298 .vendor_id = QCA_NL80211_VENDOR_ID,
6299 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6300 },
6301 {
6302 /* Index = 3*/
6303 .vendor_id = QCA_NL80211_VENDOR_ID,
6304 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6305 },
6306 {
6307 /* Index = 4*/
6308 .vendor_id = QCA_NL80211_VENDOR_ID,
6309 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6310 },
6311 {
6312 /* Index = 5*/
6313 .vendor_id = QCA_NL80211_VENDOR_ID,
6314 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6315 },
6316 {
6317 /* Index = 6*/
6318 .vendor_id = QCA_NL80211_VENDOR_ID,
6319 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6320 },
6321#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306322#ifdef WLAN_FEATURE_EXTSCAN
6323 {
6324 .vendor_id = QCA_NL80211_VENDOR_ID,
6325 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6326 },
6327 {
6328 .vendor_id = QCA_NL80211_VENDOR_ID,
6329 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6330 },
6331 {
6332 .vendor_id = QCA_NL80211_VENDOR_ID,
6333 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6334 },
6335 {
6336 .vendor_id = QCA_NL80211_VENDOR_ID,
6337 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6338 },
6339 {
6340 .vendor_id = QCA_NL80211_VENDOR_ID,
6341 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6342 },
6343 {
6344 .vendor_id = QCA_NL80211_VENDOR_ID,
6345 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6346 },
6347 {
6348 .vendor_id = QCA_NL80211_VENDOR_ID,
6349 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6350 },
6351 {
6352 .vendor_id = QCA_NL80211_VENDOR_ID,
6353 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6354 },
6355 {
6356 .vendor_id = QCA_NL80211_VENDOR_ID,
6357 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6358 },
6359 {
6360 .vendor_id = QCA_NL80211_VENDOR_ID,
6361 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6362 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306363 {
6364 .vendor_id = QCA_NL80211_VENDOR_ID,
6365 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6366 },
6367 {
6368 .vendor_id = QCA_NL80211_VENDOR_ID,
6369 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6370 },
6371 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6372 .vendor_id = QCA_NL80211_VENDOR_ID,
6373 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6374 },
6375 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6376 .vendor_id = QCA_NL80211_VENDOR_ID,
6377 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6378 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306379#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306380/*EXT TDLS*/
6381 {
6382 .vendor_id = QCA_NL80211_VENDOR_ID,
6383 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6384 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306385 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6386 .vendor_id = QCA_NL80211_VENDOR_ID,
6387 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6388 },
6389
Srinivas Dasari030bad32015-02-18 23:23:54 +05306390
6391 {
6392 .vendor_id = QCA_NL80211_VENDOR_ID,
6393 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6394 },
6395
Sushant Kaushik084f6592015-09-10 13:11:56 +05306396 {
6397 .vendor_id = QCA_NL80211_VENDOR_ID,
6398 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6399 }
6400
6401
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006402};
6403
Jeff Johnson295189b2012-06-20 16:38:30 -07006404/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306405 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306406 * This function is called by hdd_wlan_startup()
6407 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306408 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306410struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006411{
6412 struct wiphy *wiphy;
6413 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 /*
6415 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 */
6417 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6418
6419 if (!wiphy)
6420 {
6421 /* Print error and jump into err label and free the memory */
6422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6423 return NULL;
6424 }
6425
Sunil Duttc69bccb2014-05-26 21:30:20 +05306426
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 return wiphy;
6428}
6429
6430/*
6431 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306432 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 * private ioctl to change the band value
6434 */
6435int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6436{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306437 int i, j;
6438 eNVChannelEnabledType channelEnabledState;
6439
Jeff Johnsone7245742012-09-05 17:12:55 -07006440 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306441
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306442 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306444
6445 if (NULL == wiphy->bands[i])
6446 {
6447 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6448 __func__, i);
6449 continue;
6450 }
6451
6452 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6453 {
6454 struct ieee80211_supported_band *band = wiphy->bands[i];
6455
6456 channelEnabledState = vos_nv_getChannelEnabledState(
6457 band->channels[j].hw_value);
6458
6459 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6460 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306461 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306462 continue;
6463 }
6464 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6465 {
6466 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6467 continue;
6468 }
6469
6470 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6471 NV_CHANNEL_INVALID == channelEnabledState)
6472 {
6473 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6474 }
6475 else if (NV_CHANNEL_DFS == channelEnabledState)
6476 {
6477 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6478 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6479 }
6480 else
6481 {
6482 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6483 |IEEE80211_CHAN_RADAR);
6484 }
6485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 }
6487 return 0;
6488}
6489/*
6490 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491 * This function is called by hdd_wlan_startup()
6492 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 * This function is used to initialize and register wiphy structure.
6494 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306495int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006496 struct wiphy *wiphy,
6497 hdd_config_t *pCfg
6498 )
6499{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306500 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306501 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6502
Jeff Johnsone7245742012-09-05 17:12:55 -07006503 ENTER();
6504
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 /* Now bind the underlying wlan device with wiphy */
6506 set_wiphy_dev(wiphy, dev);
6507
6508 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006509
Kiet Lam6c583332013-10-14 05:37:09 +05306510#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006511 /* the flag for the other case would be initialzed in
6512 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006513 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306514#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006515
Amar Singhalfddc28c2013-09-05 13:03:40 -07006516 /* This will disable updating of NL channels from passive to
6517 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6519 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6520#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006521 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306522#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006523
Amar Singhala49cbc52013-10-08 18:37:44 -07006524
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006526 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6527 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6528 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006529 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306530#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6531 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6532#else
6533 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6534#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006535#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006536
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006537#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006538 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006539#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006540 || pCfg->isFastRoamIniFeatureEnabled
6541#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006542#ifdef FEATURE_WLAN_ESE
6543 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006544#endif
6545 )
6546 {
6547 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6548 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006549#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006550#ifdef FEATURE_WLAN_TDLS
6551 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6552 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6553#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306554#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306555 if (pCfg->configPNOScanSupport)
6556 {
6557 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6558 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6559 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6560 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6561 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306562#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006563
Abhishek Singh10d85972015-04-17 10:27:23 +05306564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6565 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6566#endif
6567
Amar Singhalfddc28c2013-09-05 13:03:40 -07006568#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006569 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6570 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006571 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006572 driver need to determine what to do with both
6573 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006574
6575 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006576#else
6577 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006578#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306580 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6581
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306582 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006583
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306584 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6585
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306587 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6588 | BIT(NL80211_IFTYPE_ADHOC)
6589 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6590 | BIT(NL80211_IFTYPE_P2P_GO)
6591 | BIT(NL80211_IFTYPE_AP);
6592
6593 if (VOS_MONITOR_MODE == hdd_get_conparam())
6594 {
6595 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006597
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306598 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006599 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6601 if( pCfg->enableMCC )
6602 {
6603 /* Currently, supports up to two channels */
6604 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006605
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306606 if( !pCfg->allowMCCGODiffBI )
6607 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006608
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306609 }
6610 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6611 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006612#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306613 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 /* Before registering we need to update the ht capabilitied based
6616 * on ini values*/
6617 if( !pCfg->ShortGI20MhzEnable )
6618 {
6619 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6620 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6621 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6622 }
6623
6624 if( !pCfg->ShortGI40MhzEnable )
6625 {
6626 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6627 }
6628
6629 if( !pCfg->nChannelBondingMode5GHz )
6630 {
6631 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6632 }
6633
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306634 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306635 if (true == hdd_is_5g_supported(pHddCtx))
6636 {
6637 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6638 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306639
6640 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6641 {
6642
6643 if (NULL == wiphy->bands[i])
6644 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306645 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306646 __func__, i);
6647 continue;
6648 }
6649
6650 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6651 {
6652 struct ieee80211_supported_band *band = wiphy->bands[i];
6653
6654 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6655 {
6656 // Enable social channels for P2P
6657 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6658 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6659 else
6660 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6661 continue;
6662 }
6663 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6664 {
6665 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6666 continue;
6667 }
6668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006669 }
6670 /*Initialise the supported cipher suite details*/
6671 wiphy->cipher_suites = hdd_cipher_suites;
6672 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6673
6674 /*signal strength in mBm (100*dBm) */
6675 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6676
6677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306678 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006679#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006680
Sunil Duttc69bccb2014-05-26 21:30:20 +05306681 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6682 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006683 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6684 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6685
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306686 EXIT();
6687 return 0;
6688}
6689
6690/* In this function we are registering wiphy. */
6691int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6692{
6693 ENTER();
6694 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 if (0 > wiphy_register(wiphy))
6696 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306697 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6699 return -EIO;
6700 }
6701
6702 EXIT();
6703 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306704}
Jeff Johnson295189b2012-06-20 16:38:30 -07006705
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306706/* In this function we are updating channel list when,
6707 regulatory domain is FCC and country code is US.
6708 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6709 As per FCC smart phone is not a indoor device.
6710 GO should not opeate on indoor channels */
6711void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6712{
6713 int j;
6714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6715 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6716 //Default counrtycode from NV at the time of wiphy initialization.
6717 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6718 &defaultCountryCode[0]))
6719 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006720 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306721 }
6722 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6723 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306724 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6725 {
6726 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6727 return;
6728 }
6729 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6730 {
6731 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6732 // Mark UNII -1 band channel as passive
6733 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6734 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6735 }
6736 }
6737}
6738
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306739/* This function registers for all frame which supplicant is interested in */
6740void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006741{
Jeff Johnson295189b2012-06-20 16:38:30 -07006742 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6743 /* Register for all P2P action, public action etc frames */
6744 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6745
Jeff Johnsone7245742012-09-05 17:12:55 -07006746 ENTER();
6747
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 /* Right now we are registering these frame when driver is getting
6749 initialized. Once we will move to 2.6.37 kernel, in which we have
6750 frame register ops, we will move this code as a part of that */
6751 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306752 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006753 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6754
6755 /* GAS Initial Response */
6756 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6757 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306758
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 /* GAS Comeback Request */
6760 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6761 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6762
6763 /* GAS Comeback Response */
6764 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6765 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6766
6767 /* P2P Public Action */
6768 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306769 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 P2P_PUBLIC_ACTION_FRAME_SIZE );
6771
6772 /* P2P Action */
6773 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6774 (v_U8_t*)P2P_ACTION_FRAME,
6775 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006776
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306777 /* WNM BSS Transition Request frame */
6778 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6779 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6780 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006781
6782 /* WNM-Notification */
6783 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6784 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6785 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006786}
6787
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306788void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006789{
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6791 /* Register for all P2P action, public action etc frames */
6792 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6793
Jeff Johnsone7245742012-09-05 17:12:55 -07006794 ENTER();
6795
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 /* Right now we are registering these frame when driver is getting
6797 initialized. Once we will move to 2.6.37 kernel, in which we have
6798 frame register ops, we will move this code as a part of that */
6799 /* GAS Initial Request */
6800
6801 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6802 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6803
6804 /* GAS Initial Response */
6805 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6806 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306807
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 /* GAS Comeback Request */
6809 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6810 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6811
6812 /* GAS Comeback Response */
6813 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6814 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6815
6816 /* P2P Public Action */
6817 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306818 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 P2P_PUBLIC_ACTION_FRAME_SIZE );
6820
6821 /* P2P Action */
6822 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6823 (v_U8_t*)P2P_ACTION_FRAME,
6824 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006825 /* WNM-Notification */
6826 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6827 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6828 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006829}
6830
6831#ifdef FEATURE_WLAN_WAPI
6832void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306833 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006834{
6835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6836 tCsrRoamSetKey setKey;
6837 v_BOOL_t isConnected = TRUE;
6838 int status = 0;
6839 v_U32_t roamId= 0xFF;
6840 tANI_U8 *pKeyPtr = NULL;
6841 int n = 0;
6842
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306843 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6844 __func__, hdd_device_modetoString(pAdapter->device_mode),
6845 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006846
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306847 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 setKey.keyId = key_index; // Store Key ID
6849 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6850 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6851 setKey.paeRole = 0 ; // the PAE role
6852 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6853 {
6854 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6855 }
6856 else
6857 {
6858 isConnected = hdd_connIsConnected(pHddStaCtx);
6859 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6860 }
6861 setKey.keyLength = key_Len;
6862 pKeyPtr = setKey.Key;
6863 memcpy( pKeyPtr, key, key_Len);
6864
Arif Hussain6d2a3322013-11-17 19:50:10 -08006865 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 __func__, key_Len);
6867 for (n = 0 ; n < key_Len; n++)
6868 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6869 __func__,n,setKey.Key[n]);
6870
6871 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6872 if ( isConnected )
6873 {
6874 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6875 pAdapter->sessionId, &setKey, &roamId );
6876 }
6877 if ( status != 0 )
6878 {
6879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6880 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6881 __LINE__, status );
6882 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6883 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306884 /* Need to clear any trace of key value in the memory.
6885 * Thus zero out the memory even though it is local
6886 * variable.
6887 */
6888 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006889}
6890#endif /* FEATURE_WLAN_WAPI*/
6891
6892#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306893int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 beacon_data_t **ppBeacon,
6895 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006896#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306897int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006898 beacon_data_t **ppBeacon,
6899 struct cfg80211_beacon_data *params,
6900 int dtim_period)
6901#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902{
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 int size;
6904 beacon_data_t *beacon = NULL;
6905 beacon_data_t *old = NULL;
6906 int head_len,tail_len;
6907
Jeff Johnsone7245742012-09-05 17:12:55 -07006908 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306910 {
6911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6912 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006913 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306914 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006915
6916 old = pAdapter->sessionCtx.ap.beacon;
6917
6918 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306919 {
6920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6921 FL("session(%d) old and new heads points to NULL"),
6922 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306924 }
6925
6926 if (params->tail && !params->tail_len)
6927 {
6928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6929 FL("tail_len is zero but tail is not NULL"));
6930 return -EINVAL;
6931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006932
Jeff Johnson295189b2012-06-20 16:38:30 -07006933#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6934 /* Kernel 3.0 is not updating dtim_period for set beacon */
6935 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306936 {
6937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6938 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006941#endif
6942
6943 if(params->head)
6944 head_len = params->head_len;
6945 else
6946 head_len = old->head_len;
6947
6948 if(params->tail || !old)
6949 tail_len = params->tail_len;
6950 else
6951 tail_len = old->tail_len;
6952
6953 size = sizeof(beacon_data_t) + head_len + tail_len;
6954
6955 beacon = kzalloc(size, GFP_KERNEL);
6956
6957 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306958 {
6959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6960 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306962 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006963
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006964#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 if(params->dtim_period || !old )
6966 beacon->dtim_period = params->dtim_period;
6967 else
6968 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969#else
6970 if(dtim_period || !old )
6971 beacon->dtim_period = dtim_period;
6972 else
6973 beacon->dtim_period = old->dtim_period;
6974#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306975
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6977 beacon->tail = beacon->head + head_len;
6978 beacon->head_len = head_len;
6979 beacon->tail_len = tail_len;
6980
6981 if(params->head) {
6982 memcpy (beacon->head,params->head,beacon->head_len);
6983 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306984 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 if(old)
6986 memcpy (beacon->head,old->head,beacon->head_len);
6987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306988
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 if(params->tail) {
6990 memcpy (beacon->tail,params->tail,beacon->tail_len);
6991 }
6992 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306993 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 memcpy (beacon->tail,old->tail,beacon->tail_len);
6995 }
6996
6997 *ppBeacon = beacon;
6998
6999 kfree(old);
7000
7001 return 0;
7002
7003}
Jeff Johnson295189b2012-06-20 16:38:30 -07007004
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307005v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
7006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7007 const v_U8_t *pIes,
7008#else
7009 v_U8_t *pIes,
7010#endif
7011 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007012{
7013 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307014 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307016
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307018 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 elem_id = ptr[0];
7020 elem_len = ptr[1];
7021 left -= 2;
7022 if(elem_len > left)
7023 {
7024 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007025 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 eid,elem_len,left);
7027 return NULL;
7028 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307029 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 {
7031 return ptr;
7032 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307033
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 left -= elem_len;
7035 ptr += (elem_len + 2);
7036 }
7037 return NULL;
7038}
7039
Jeff Johnson295189b2012-06-20 16:38:30 -07007040/* Check if rate is 11g rate or not */
7041static int wlan_hdd_rate_is_11g(u8 rate)
7042{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007043 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 u8 i;
7045 for (i = 0; i < 8; i++)
7046 {
7047 if(rate == gRateArray[i])
7048 return TRUE;
7049 }
7050 return FALSE;
7051}
7052
7053/* Check for 11g rate and set proper 11g only mode */
7054static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7055 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7056{
7057 u8 i, num_rates = pIe[0];
7058
7059 pIe += 1;
7060 for ( i = 0; i < num_rates; i++)
7061 {
7062 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7063 {
7064 /* If rate set have 11g rate than change the mode to 11G */
7065 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7066 if (pIe[i] & BASIC_RATE_MASK)
7067 {
7068 /* If we have 11g rate as basic rate, it means mode
7069 is 11g only mode.
7070 */
7071 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7072 *pCheckRatesfor11g = FALSE;
7073 }
7074 }
7075 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7076 {
7077 *require_ht = TRUE;
7078 }
7079 }
7080 return;
7081}
7082
7083static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7084{
7085 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7086 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7087 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7088 u8 checkRatesfor11g = TRUE;
7089 u8 require_ht = FALSE;
7090 u8 *pIe=NULL;
7091
7092 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7093
7094 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7095 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7096 if (pIe != NULL)
7097 {
7098 pIe += 1;
7099 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7100 &pConfig->SapHw_mode);
7101 }
7102
7103 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7104 WLAN_EID_EXT_SUPP_RATES);
7105 if (pIe != NULL)
7106 {
7107
7108 pIe += 1;
7109 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7110 &pConfig->SapHw_mode);
7111 }
7112
7113 if( pConfig->channel > 14 )
7114 {
7115 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7116 }
7117
7118 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7119 WLAN_EID_HT_CAPABILITY);
7120
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307121 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 {
7123 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7124 if(require_ht)
7125 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7126 }
7127}
7128
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307129static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7130 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7131{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007132 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307133 v_U8_t *pIe = NULL;
7134 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7135
7136 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7137 pBeacon->tail, pBeacon->tail_len);
7138
7139 if (pIe)
7140 {
7141 ielen = pIe[1] + 2;
7142 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7143 {
7144 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7145 }
7146 else
7147 {
7148 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7149 return -EINVAL;
7150 }
7151 *total_ielen += ielen;
7152 }
7153 return 0;
7154}
7155
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007156static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7157 v_U8_t *genie, v_U8_t *total_ielen)
7158{
7159 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7160 int left = pBeacon->tail_len;
7161 v_U8_t *ptr = pBeacon->tail;
7162 v_U8_t elem_id, elem_len;
7163 v_U16_t ielen = 0;
7164
7165 if ( NULL == ptr || 0 == left )
7166 return;
7167
7168 while (left >= 2)
7169 {
7170 elem_id = ptr[0];
7171 elem_len = ptr[1];
7172 left -= 2;
7173 if (elem_len > left)
7174 {
7175 hddLog( VOS_TRACE_LEVEL_ERROR,
7176 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7177 elem_id, elem_len, left);
7178 return;
7179 }
7180 if (IE_EID_VENDOR == elem_id)
7181 {
7182 /* skipping the VSIE's which we don't want to include or
7183 * it will be included by existing code
7184 */
7185 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7186#ifdef WLAN_FEATURE_WFD
7187 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7188#endif
7189 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7190 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7191 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7192 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7193 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7194 {
7195 ielen = ptr[1] + 2;
7196 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7197 {
7198 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7199 *total_ielen += ielen;
7200 }
7201 else
7202 {
7203 hddLog( VOS_TRACE_LEVEL_ERROR,
7204 "IE Length is too big "
7205 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7206 elem_id, elem_len, *total_ielen);
7207 }
7208 }
7209 }
7210
7211 left -= elem_len;
7212 ptr += (elem_len + 2);
7213 }
7214 return;
7215}
7216
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007217#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007218static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7219 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007220#else
7221static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7222 struct cfg80211_beacon_data *params)
7223#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007224{
7225 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307226 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007228 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007229
7230 genie = vos_mem_malloc(MAX_GENIE_LEN);
7231
7232 if(genie == NULL) {
7233
7234 return -ENOMEM;
7235 }
7236
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307237 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7238 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307240 hddLog(LOGE,
7241 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307242 ret = -EINVAL;
7243 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 }
7245
7246#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307247 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7248 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7249 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307250 hddLog(LOGE,
7251 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307252 ret = -EINVAL;
7253 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007254 }
7255#endif
7256
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307257 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7258 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307260 hddLog(LOGE,
7261 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307262 ret = -EINVAL;
7263 goto done;
7264 }
7265
7266 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7267 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007268 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007269 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007270
7271 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7272 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7273 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7274 {
7275 hddLog(LOGE,
7276 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007277 ret = -EINVAL;
7278 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 }
7280
7281 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7282 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7283 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7284 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7285 ==eHAL_STATUS_FAILURE)
7286 {
7287 hddLog(LOGE,
7288 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007289 ret = -EINVAL;
7290 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 }
7292
7293 // Added for ProResp IE
7294 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7295 {
7296 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7297 u8 probe_rsp_ie_len[3] = {0};
7298 u8 counter = 0;
7299 /* Check Probe Resp Length if it is greater then 255 then Store
7300 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7301 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7302 Store More then 255 bytes into One Variable.
7303 */
7304 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7305 {
7306 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7307 {
7308 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7309 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7310 }
7311 else
7312 {
7313 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7314 rem_probe_resp_ie_len = 0;
7315 }
7316 }
7317
7318 rem_probe_resp_ie_len = 0;
7319
7320 if (probe_rsp_ie_len[0] > 0)
7321 {
7322 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7323 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7324 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7325 probe_rsp_ie_len[0], NULL,
7326 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7327 {
7328 hddLog(LOGE,
7329 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007330 ret = -EINVAL;
7331 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 }
7333 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7334 }
7335
7336 if (probe_rsp_ie_len[1] > 0)
7337 {
7338 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7339 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7340 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7341 probe_rsp_ie_len[1], NULL,
7342 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7343 {
7344 hddLog(LOGE,
7345 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007346 ret = -EINVAL;
7347 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 }
7349 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7350 }
7351
7352 if (probe_rsp_ie_len[2] > 0)
7353 {
7354 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7355 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7356 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7357 probe_rsp_ie_len[2], NULL,
7358 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7359 {
7360 hddLog(LOGE,
7361 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007362 ret = -EINVAL;
7363 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 }
7365 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7366 }
7367
7368 if (probe_rsp_ie_len[1] == 0 )
7369 {
7370 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7371 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7372 eANI_BOOLEAN_FALSE) )
7373 {
7374 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007375 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 }
7377 }
7378
7379 if (probe_rsp_ie_len[2] == 0 )
7380 {
7381 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7382 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7383 eANI_BOOLEAN_FALSE) )
7384 {
7385 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007386 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 }
7388 }
7389
7390 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7391 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7392 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7393 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7394 == eHAL_STATUS_FAILURE)
7395 {
7396 hddLog(LOGE,
7397 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007398 ret = -EINVAL;
7399 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 }
7401 }
7402 else
7403 {
7404 // Reset WNI_CFG_PROBE_RSP Flags
7405 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7406
7407 hddLog(VOS_TRACE_LEVEL_INFO,
7408 "%s: No Probe Response IE received in set beacon",
7409 __func__);
7410 }
7411
7412 // Added for AssocResp IE
7413 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7414 {
7415 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7416 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7417 params->assocresp_ies_len, NULL,
7418 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7419 {
7420 hddLog(LOGE,
7421 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007422 ret = -EINVAL;
7423 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 }
7425
7426 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7427 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7428 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7429 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7430 == eHAL_STATUS_FAILURE)
7431 {
7432 hddLog(LOGE,
7433 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007434 ret = -EINVAL;
7435 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 }
7437 }
7438 else
7439 {
7440 hddLog(VOS_TRACE_LEVEL_INFO,
7441 "%s: No Assoc Response IE received in set beacon",
7442 __func__);
7443
7444 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7445 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7446 eANI_BOOLEAN_FALSE) )
7447 {
7448 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007449 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 }
7451 }
7452
Jeff Johnsone7245742012-09-05 17:12:55 -07007453done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307455 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007456}
Jeff Johnson295189b2012-06-20 16:38:30 -07007457
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307458/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 * FUNCTION: wlan_hdd_validate_operation_channel
7460 * called by wlan_hdd_cfg80211_start_bss() and
7461 * wlan_hdd_cfg80211_set_channel()
7462 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463 * channel list.
7464 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007465VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007466{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307467
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 v_U32_t num_ch = 0;
7469 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7470 u32 indx = 0;
7471 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307472 v_U8_t fValidChannel = FALSE, count = 0;
7473 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307474
Jeff Johnson295189b2012-06-20 16:38:30 -07007475 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7476
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307477 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307479 /* Validate the channel */
7480 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307482 if ( channel == rfChannels[count].channelNum )
7483 {
7484 fValidChannel = TRUE;
7485 break;
7486 }
7487 }
7488 if (fValidChannel != TRUE)
7489 {
7490 hddLog(VOS_TRACE_LEVEL_ERROR,
7491 "%s: Invalid Channel [%d]", __func__, channel);
7492 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 }
7494 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307495 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307497 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7498 valid_ch, &num_ch))
7499 {
7500 hddLog(VOS_TRACE_LEVEL_ERROR,
7501 "%s: failed to get valid channel list", __func__);
7502 return VOS_STATUS_E_FAILURE;
7503 }
7504 for (indx = 0; indx < num_ch; indx++)
7505 {
7506 if (channel == valid_ch[indx])
7507 {
7508 break;
7509 }
7510 }
7511
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307512 if (indx >= num_ch)
7513 {
7514 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7515 {
7516 eCsrBand band;
7517 unsigned int freq;
7518
7519 sme_GetFreqBand(hHal, &band);
7520
7521 if (eCSR_BAND_5G == band)
7522 {
7523#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7524 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7525 {
7526 freq = ieee80211_channel_to_frequency(channel,
7527 IEEE80211_BAND_2GHZ);
7528 }
7529 else
7530 {
7531 freq = ieee80211_channel_to_frequency(channel,
7532 IEEE80211_BAND_5GHZ);
7533 }
7534#else
7535 freq = ieee80211_channel_to_frequency(channel);
7536#endif
7537 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7538 return VOS_STATUS_SUCCESS;
7539 }
7540 }
7541
7542 hddLog(VOS_TRACE_LEVEL_ERROR,
7543 "%s: Invalid Channel [%d]", __func__, channel);
7544 return VOS_STATUS_E_FAILURE;
7545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307547
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307549
Jeff Johnson295189b2012-06-20 16:38:30 -07007550}
7551
Viral Modi3a32cc52013-02-08 11:14:52 -08007552/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307553 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007554 * This function is used to set the channel number
7555 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307556static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007557 struct ieee80211_channel *chan,
7558 enum nl80211_channel_type channel_type
7559 )
7560{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307561 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007562 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007563 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007564 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307565 hdd_context_t *pHddCtx;
7566 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007567
7568 ENTER();
7569
7570 if( NULL == dev )
7571 {
7572 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007573 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007574 return -ENODEV;
7575 }
7576 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307577
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307578 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7579 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7580 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007581 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307582 "%s: device_mode = %s (%d) freq = %d", __func__,
7583 hdd_device_modetoString(pAdapter->device_mode),
7584 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307585
7586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7587 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307588 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007589 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307590 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007591 }
7592
7593 /*
7594 * Do freq to chan conversion
7595 * TODO: for 11a
7596 */
7597
7598 channel = ieee80211_frequency_to_channel(freq);
7599
7600 /* Check freq range */
7601 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7602 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7603 {
7604 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007605 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007606 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7607 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7608 return -EINVAL;
7609 }
7610
7611 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7612
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307613 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7614 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007615 {
7616 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7617 {
7618 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007619 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007620 return -EINVAL;
7621 }
7622 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7623 "%s: set channel to [%d] for device mode =%d",
7624 __func__, channel,pAdapter->device_mode);
7625 }
7626 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007627 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007628 )
7629 {
7630 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7631 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7632 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7633
7634 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7635 {
7636 /* Link is up then return cant set channel*/
7637 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007638 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007639 return -EINVAL;
7640 }
7641
7642 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7643 pHddStaCtx->conn_info.operationChannel = channel;
7644 pRoamProfile->ChannelInfo.ChannelList =
7645 &pHddStaCtx->conn_info.operationChannel;
7646 }
7647 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007648 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007649 )
7650 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307651 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7652 {
7653 if(VOS_STATUS_SUCCESS !=
7654 wlan_hdd_validate_operation_channel(pAdapter,channel))
7655 {
7656 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007657 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307658 return -EINVAL;
7659 }
7660 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7661 }
7662 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007663 {
7664 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7665
7666 /* If auto channel selection is configured as enable/ 1 then ignore
7667 channel set by supplicant
7668 */
7669 if ( cfg_param->apAutoChannelSelection )
7670 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307671 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7672 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007673 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307674 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7675 __func__, hdd_device_modetoString(pAdapter->device_mode),
7676 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007677 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307678 else
7679 {
7680 if(VOS_STATUS_SUCCESS !=
7681 wlan_hdd_validate_operation_channel(pAdapter,channel))
7682 {
7683 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007684 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307685 return -EINVAL;
7686 }
7687 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7688 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007689 }
7690 }
7691 else
7692 {
7693 hddLog(VOS_TRACE_LEVEL_FATAL,
7694 "%s: Invalid device mode failed to set valid channel", __func__);
7695 return -EINVAL;
7696 }
7697 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307698 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007699}
7700
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307701static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7702 struct net_device *dev,
7703 struct ieee80211_channel *chan,
7704 enum nl80211_channel_type channel_type
7705 )
7706{
7707 int ret;
7708
7709 vos_ssr_protect(__func__);
7710 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7711 vos_ssr_unprotect(__func__);
7712
7713 return ret;
7714}
7715
Jeff Johnson295189b2012-06-20 16:38:30 -07007716#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7717static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7718 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007719#else
7720static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7721 struct cfg80211_beacon_data *params,
7722 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307723 enum nl80211_hidden_ssid hidden_ssid,
7724 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007725#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007726{
7727 tsap_Config_t *pConfig;
7728 beacon_data_t *pBeacon = NULL;
7729 struct ieee80211_mgmt *pMgmt_frame;
7730 v_U8_t *pIe=NULL;
7731 v_U16_t capab_info;
7732 eCsrAuthType RSNAuthType;
7733 eCsrEncryptionType RSNEncryptType;
7734 eCsrEncryptionType mcRSNEncryptType;
7735 int status = VOS_STATUS_SUCCESS;
7736 tpWLAN_SAPEventCB pSapEventCallback;
7737 hdd_hostapd_state_t *pHostapdState;
7738 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7739 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307740 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307742 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007744 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307745 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007746 v_BOOL_t MFPCapable = VOS_FALSE;
7747 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307748 v_BOOL_t sapEnable11AC =
7749 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 ENTER();
7751
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307752 iniConfig = pHddCtx->cfg_ini;
7753
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7755
7756 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7757
7758 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7759
7760 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7761
7762 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7763
7764 //channel is already set in the set_channel Call back
7765 //pConfig->channel = pCommitConfig->channel;
7766
7767 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307768 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007769 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7770
7771 pConfig->dtim_period = pBeacon->dtim_period;
7772
Arif Hussain6d2a3322013-11-17 19:50:10 -08007773 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 pConfig->dtim_period);
7775
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007776 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007777 {
7778 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007779 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307780 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7781 {
7782 tANI_BOOLEAN restartNeeded;
7783 pConfig->ieee80211d = 1;
7784 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7785 sme_setRegInfo(hHal, pConfig->countryCode);
7786 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7787 }
7788 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007790 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007791 pConfig->ieee80211d = 1;
7792 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7793 sme_setRegInfo(hHal, pConfig->countryCode);
7794 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007796 else
7797 {
7798 pConfig->ieee80211d = 0;
7799 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307800 /*
7801 * If auto channel is configured i.e. channel is 0,
7802 * so skip channel validation.
7803 */
7804 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7805 {
7806 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7807 {
7808 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007809 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307810 return -EINVAL;
7811 }
7812 }
7813 else
7814 {
7815 if(1 != pHddCtx->is_dynamic_channel_range_set)
7816 {
7817 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7818 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7819 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7820 }
7821 pHddCtx->is_dynamic_channel_range_set = 0;
7822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007824 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007825 {
7826 pConfig->ieee80211d = 0;
7827 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307828
7829#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7830 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7831 pConfig->authType = eSAP_OPEN_SYSTEM;
7832 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7833 pConfig->authType = eSAP_SHARED_KEY;
7834 else
7835 pConfig->authType = eSAP_AUTO_SWITCH;
7836#else
7837 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7838 pConfig->authType = eSAP_OPEN_SYSTEM;
7839 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7840 pConfig->authType = eSAP_SHARED_KEY;
7841 else
7842 pConfig->authType = eSAP_AUTO_SWITCH;
7843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007844
7845 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307846
7847 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7849
7850 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7851
7852 /*Set wps station to configured*/
7853 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7854
7855 if(pIe)
7856 {
7857 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7858 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007859 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 return -EINVAL;
7861 }
7862 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7863 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007864 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 /* Check 15 bit of WPS IE as it contain information for wps state
7866 * WPS state
7867 */
7868 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7869 {
7870 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7871 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7872 {
7873 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7874 }
7875 }
7876 }
7877 else
7878 {
7879 pConfig->wps_state = SAP_WPS_DISABLED;
7880 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307881 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007882
c_hpothufe599e92014-06-16 11:38:55 +05307883 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7884 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7885 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7886 eCSR_ENCRYPT_TYPE_NONE;
7887
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 pConfig->RSNWPAReqIELength = 0;
7889 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 WLAN_EID_RSN);
7892 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307893 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7895 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7896 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307897 /* The actual processing may eventually be more extensive than
7898 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 * by the app.
7900 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307901 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7903 &RSNEncryptType,
7904 &mcRSNEncryptType,
7905 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007906 &MFPCapable,
7907 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 pConfig->pRSNWPAReqIE[1]+2,
7909 pConfig->pRSNWPAReqIE );
7910
7911 if( VOS_STATUS_SUCCESS == status )
7912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307913 /* Now copy over all the security attributes you have
7914 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 * */
7916 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7917 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7918 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7919 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307920 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007921 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7923 }
7924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307925
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7927 pBeacon->tail, pBeacon->tail_len);
7928
7929 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7930 {
7931 if (pConfig->pRSNWPAReqIE)
7932 {
7933 /*Mixed mode WPA/WPA2*/
7934 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7935 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7936 }
7937 else
7938 {
7939 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7940 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7941 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307942 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7944 &RSNEncryptType,
7945 &mcRSNEncryptType,
7946 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007947 &MFPCapable,
7948 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 pConfig->pRSNWPAReqIE[1]+2,
7950 pConfig->pRSNWPAReqIE );
7951
7952 if( VOS_STATUS_SUCCESS == status )
7953 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307954 /* Now copy over all the security attributes you have
7955 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 * */
7957 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7958 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7959 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7960 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307961 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007962 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7964 }
7965 }
7966 }
7967
Jeff Johnson4416a782013-03-25 14:17:50 -07007968 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7969 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7970 return -EINVAL;
7971 }
7972
Jeff Johnson295189b2012-06-20 16:38:30 -07007973 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7974
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007975#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 if (params->ssid != NULL)
7977 {
7978 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7979 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7980 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7981 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7982 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007983#else
7984 if (ssid != NULL)
7985 {
7986 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7987 pConfig->SSIDinfo.ssid.length = ssid_len;
7988 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7989 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7990 }
7991#endif
7992
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307995
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 /* default value */
7997 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7998 pConfig->num_accept_mac = 0;
7999 pConfig->num_deny_mac = 0;
8000
8001 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8002 pBeacon->tail, pBeacon->tail_len);
8003
8004 /* pIe for black list is following form:
8005 type : 1 byte
8006 length : 1 byte
8007 OUI : 4 bytes
8008 acl type : 1 byte
8009 no of mac addr in black list: 1 byte
8010 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308011 */
8012 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 {
8014 pConfig->SapMacaddr_acl = pIe[6];
8015 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008016 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308018 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8019 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8021 for (i = 0; i < pConfig->num_deny_mac; i++)
8022 {
8023 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8024 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 }
8027 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8028 pBeacon->tail, pBeacon->tail_len);
8029
8030 /* pIe for white list is following form:
8031 type : 1 byte
8032 length : 1 byte
8033 OUI : 4 bytes
8034 acl type : 1 byte
8035 no of mac addr in white list: 1 byte
8036 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308037 */
8038 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 {
8040 pConfig->SapMacaddr_acl = pIe[6];
8041 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008042 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308044 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8045 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8047 for (i = 0; i < pConfig->num_accept_mac; i++)
8048 {
8049 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8050 acl_entry++;
8051 }
8052 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308053
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8055
Jeff Johnsone7245742012-09-05 17:12:55 -07008056#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008057 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308058 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8059 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308060 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8061 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008062 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8063 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308064 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8065 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008066 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308067 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008068 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308069 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008070
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308071 /* If ACS disable and selected channel <= 14
8072 * OR
8073 * ACS enabled and ACS operating band is choosen as 2.4
8074 * AND
8075 * VHT in 2.4G Disabled
8076 * THEN
8077 * Fallback to 11N mode
8078 */
8079 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8080 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308081 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308082 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008083 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308084 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8085 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008086 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8087 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008088 }
8089#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 // ht_capab is not what the name conveys,this is used for protection bitmap
8092 pConfig->ht_capab =
8093 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8094
8095 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8096 {
8097 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8098 return -EINVAL;
8099 }
8100
8101 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308102 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8104 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308105 pConfig->obssProtEnabled =
8106 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008107
Chet Lanctot8cecea22014-02-11 19:09:36 -08008108#ifdef WLAN_FEATURE_11W
8109 pConfig->mfpCapable = MFPCapable;
8110 pConfig->mfpRequired = MFPRequired;
8111 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8112 pConfig->mfpCapable, pConfig->mfpRequired);
8113#endif
8114
Arif Hussain6d2a3322013-11-17 19:50:10 -08008115 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008117 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8118 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8119 (int)pConfig->channel);
8120 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8121 pConfig->SapHw_mode, pConfig->privacy,
8122 pConfig->authType);
8123 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8124 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8125 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8126 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008127
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308128 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 {
8130 //Bss already started. just return.
8131 //TODO Probably it should update some beacon params.
8132 hddLog( LOGE, "Bss Already started...Ignore the request");
8133 EXIT();
8134 return 0;
8135 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308136
Agarwal Ashish51325b52014-06-16 16:50:49 +05308137 if (vos_max_concurrent_connections_reached()) {
8138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8139 return -EINVAL;
8140 }
8141
Jeff Johnson295189b2012-06-20 16:38:30 -07008142 pConfig->persona = pHostapdAdapter->device_mode;
8143
Peng Xu2446a892014-09-05 17:21:18 +05308144 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8145 if ( NULL != psmeConfig)
8146 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308147 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308148 sme_GetConfigParam(hHal, psmeConfig);
8149 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308150#ifdef WLAN_FEATURE_AP_HT40_24G
8151 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8152 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8153 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8154 {
8155 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8156 sme_UpdateConfig (hHal, psmeConfig);
8157 }
8158#endif
Peng Xu2446a892014-09-05 17:21:18 +05308159 vos_mem_free(psmeConfig);
8160 }
Peng Xuafc34e32014-09-25 13:23:55 +05308161 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308162
Jeff Johnson295189b2012-06-20 16:38:30 -07008163 pSapEventCallback = hdd_hostapd_SAPEventCB;
8164 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8165 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8166 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008167 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 return -EINVAL;
8169 }
8170
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308171 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8173
8174 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308177 {
8178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008179 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008180 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 VOS_ASSERT(0);
8182 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308183
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308185 /* Initialize WMM configuation */
8186 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308187 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008188
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008189#ifdef WLAN_FEATURE_P2P_DEBUG
8190 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8191 {
8192 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8193 {
8194 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8195 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008196 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008197 }
8198 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8199 {
8200 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8201 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008202 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008203 }
8204 }
8205#endif
8206
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 pHostapdState->bCommit = TRUE;
8208 EXIT();
8209
8210 return 0;
8211}
8212
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008213#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308214static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308215 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 struct beacon_parameters *params)
8217{
8218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308219 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308220 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008221
8222 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308223
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8225 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8226 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308227 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8228 hdd_device_modetoString(pAdapter->device_mode),
8229 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008230
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8232 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308233 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008234 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308235 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008236 }
8237
Agarwal Ashish51325b52014-06-16 16:50:49 +05308238 if (vos_max_concurrent_connections_reached()) {
8239 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8240 return -EINVAL;
8241 }
8242
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308243 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 )
8246 {
8247 beacon_data_t *old,*new;
8248
8249 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308250
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308252 {
8253 hddLog(VOS_TRACE_LEVEL_WARN,
8254 FL("already beacon info added to session(%d)"),
8255 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308257 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008258
8259 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8260
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308261 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 {
8263 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008264 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 return -EINVAL;
8266 }
8267
8268 pAdapter->sessionCtx.ap.beacon = new;
8269
8270 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8271 }
8272
8273 EXIT();
8274 return status;
8275}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308276
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308277static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8278 struct net_device *dev,
8279 struct beacon_parameters *params)
8280{
8281 int ret;
8282
8283 vos_ssr_protect(__func__);
8284 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8285 vos_ssr_unprotect(__func__);
8286
8287 return ret;
8288}
8289
8290static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 struct net_device *dev,
8292 struct beacon_parameters *params)
8293{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308295 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8296 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308297 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008298
8299 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308300
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308301 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8302 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8303 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8304 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8305 __func__, hdd_device_modetoString(pAdapter->device_mode),
8306 pAdapter->device_mode);
8307
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308310 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308312 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008313 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308314
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308315 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308317 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 {
8319 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308320
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308322
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308324 {
8325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 FL("session(%d) old and new heads points to NULL"),
8327 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308329 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008330
8331 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8332
8333 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308334 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008335 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 return -EINVAL;
8337 }
8338
8339 pAdapter->sessionCtx.ap.beacon = new;
8340
8341 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8342 }
8343
8344 EXIT();
8345 return status;
8346}
8347
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308348static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8349 struct net_device *dev,
8350 struct beacon_parameters *params)
8351{
8352 int ret;
8353
8354 vos_ssr_protect(__func__);
8355 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8356 vos_ssr_unprotect(__func__);
8357
8358 return ret;
8359}
8360
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008361#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8362
8363#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308364static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008366#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308367static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008368 struct net_device *dev)
8369#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008370{
8371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008372 hdd_context_t *pHddCtx = NULL;
8373 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308374 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308375 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376
8377 ENTER();
8378
8379 if (NULL == pAdapter)
8380 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008382 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 return -ENODEV;
8384 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008385
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308386 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8387 TRACE_CODE_HDD_CFG80211_STOP_AP,
8388 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8390 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308391 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008392 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308393 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008394 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008395
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008396 pScanInfo = &pHddCtx->scan_info;
8397
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8399 __func__, hdd_device_modetoString(pAdapter->device_mode),
8400 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008401
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308402 ret = wlan_hdd_scan_abort(pAdapter);
8403
Girish Gowli4bf7a632014-06-12 13:42:11 +05308404 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008405 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8407 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308408
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308409 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008410 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8412 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008413
Jeff Johnsone7245742012-09-05 17:12:55 -07008414 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308415 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008416 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308417 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008418 }
8419
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308420 /* Delete all associated STAs before stopping AP/P2P GO */
8421 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308422 hdd_hostapd_stop(dev);
8423
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 )
8427 {
8428 beacon_data_t *old;
8429
8430 old = pAdapter->sessionCtx.ap.beacon;
8431
8432 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308433 {
8434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8435 FL("session(%d) beacon data points to NULL"),
8436 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308438 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008439
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008441
8442 mutex_lock(&pHddCtx->sap_lock);
8443 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8444 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008445 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 {
8447 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8448
8449 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8450
8451 if (!VOS_IS_STATUS_SUCCESS(status))
8452 {
8453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008454 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308456 }
8457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308459 /* BSS stopped, clear the active sessions for this device mode */
8460 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 }
8462 mutex_unlock(&pHddCtx->sap_lock);
8463
8464 if(status != VOS_STATUS_SUCCESS)
8465 {
8466 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008467 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 return -EINVAL;
8469 }
8470
Jeff Johnson4416a782013-03-25 14:17:50 -07008471 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8473 ==eHAL_STATUS_FAILURE)
8474 {
8475 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008476 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 }
8478
Jeff Johnson4416a782013-03-25 14:17:50 -07008479 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8481 eANI_BOOLEAN_FALSE) )
8482 {
8483 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008484 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 }
8486
8487 // Reset WNI_CFG_PROBE_RSP Flags
8488 wlan_hdd_reset_prob_rspies(pAdapter);
8489
8490 pAdapter->sessionCtx.ap.beacon = NULL;
8491 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008492#ifdef WLAN_FEATURE_P2P_DEBUG
8493 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8494 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8495 {
8496 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8497 "GO got removed");
8498 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8499 }
8500#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 }
8502 EXIT();
8503 return status;
8504}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008505
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308506#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8507static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8508 struct net_device *dev)
8509{
8510 int ret;
8511
8512 vos_ssr_protect(__func__);
8513 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8514 vos_ssr_unprotect(__func__);
8515
8516 return ret;
8517}
8518#else
8519static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8520 struct net_device *dev)
8521{
8522 int ret;
8523
8524 vos_ssr_protect(__func__);
8525 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8526 vos_ssr_unprotect(__func__);
8527
8528 return ret;
8529}
8530#endif
8531
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008532#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8533
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308534static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308535 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008536 struct cfg80211_ap_settings *params)
8537{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308538 hdd_adapter_t *pAdapter;
8539 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308540 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008541
8542 ENTER();
8543
Girish Gowlib143d7a2015-02-18 19:39:55 +05308544 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008545 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308547 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308548 return -ENODEV;
8549 }
8550
8551 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8552 if (NULL == pAdapter)
8553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308555 "%s: HDD adapter is Null", __func__);
8556 return -ENODEV;
8557 }
8558
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308559 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8560 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8561 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308562 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8563 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308565 "%s: HDD adapter magic is invalid", __func__);
8566 return -ENODEV;
8567 }
8568
8569 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308570 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308571 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308572 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308573 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308574 }
8575
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308576 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8577 __func__, hdd_device_modetoString(pAdapter->device_mode),
8578 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308579
8580 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008581 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008582 )
8583 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308584 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008585
8586 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308587
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008588 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308589 {
8590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8591 FL("already beacon info added to session(%d)"),
8592 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008593 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308594 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008595
Girish Gowlib143d7a2015-02-18 19:39:55 +05308596#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8597 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8598 &new,
8599 &params->beacon);
8600#else
8601 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8602 &new,
8603 &params->beacon,
8604 params->dtim_period);
8605#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008606
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308607 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008608 {
8609 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308610 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008611 return -EINVAL;
8612 }
8613 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008615 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8616#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8617 params->channel, params->channel_type);
8618#else
8619 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8620#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008621#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008622 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308623 params->ssid_len, params->hidden_ssid,
8624 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008625 }
8626
8627 EXIT();
8628 return status;
8629}
8630
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308631static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8632 struct net_device *dev,
8633 struct cfg80211_ap_settings *params)
8634{
8635 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008636
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308637 vos_ssr_protect(__func__);
8638 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8639 vos_ssr_unprotect(__func__);
8640
8641 return ret;
8642}
8643
8644static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008645 struct net_device *dev,
8646 struct cfg80211_beacon_data *params)
8647{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308648 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308649 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308650 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008651
8652 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308653
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308654 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8655 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8656 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008658 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308659
8660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8661 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308662 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008663 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308664 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008665 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008666
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308667 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308669 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008670 {
8671 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308672
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008673 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308674
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008675 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308676 {
8677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8678 FL("session(%d) beacon data points to NULL"),
8679 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008680 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308681 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008682
8683 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8684
8685 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308686 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008687 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008688 return -EINVAL;
8689 }
8690
8691 pAdapter->sessionCtx.ap.beacon = new;
8692
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308693 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8694 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008695 }
8696
8697 EXIT();
8698 return status;
8699}
8700
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308701static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8702 struct net_device *dev,
8703 struct cfg80211_beacon_data *params)
8704{
8705 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008706
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308707 vos_ssr_protect(__func__);
8708 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8709 vos_ssr_unprotect(__func__);
8710
8711 return ret;
8712}
8713
8714#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008715
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308716static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 struct net_device *dev,
8718 struct bss_parameters *params)
8719{
8720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308721 hdd_context_t *pHddCtx;
8722 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
8724 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308725
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308726 if (NULL == pAdapter)
8727 {
8728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8729 "%s: HDD adapter is Null", __func__);
8730 return -ENODEV;
8731 }
8732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308733 ret = wlan_hdd_validate_context(pHddCtx);
8734 if (0 != ret)
8735 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308736 return ret;
8737 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8739 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8740 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308741 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8742 __func__, hdd_device_modetoString(pAdapter->device_mode),
8743 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008744
8745 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308747 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 {
8749 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8750 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308751 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 {
8753 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 }
8756
8757 EXIT();
8758 return 0;
8759}
8760
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308761static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8762 struct net_device *dev,
8763 struct bss_parameters *params)
8764{
8765 int ret;
8766
8767 vos_ssr_protect(__func__);
8768 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8769 vos_ssr_unprotect(__func__);
8770
8771 return ret;
8772}
Kiet Lam10841362013-11-01 11:36:50 +05308773/* FUNCTION: wlan_hdd_change_country_code_cd
8774* to wait for contry code completion
8775*/
8776void* wlan_hdd_change_country_code_cb(void *pAdapter)
8777{
8778 hdd_adapter_t *call_back_pAdapter = pAdapter;
8779 complete(&call_back_pAdapter->change_country_code);
8780 return NULL;
8781}
8782
Jeff Johnson295189b2012-06-20 16:38:30 -07008783/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308784 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8786 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308787int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008788 struct net_device *ndev,
8789 enum nl80211_iftype type,
8790 u32 *flags,
8791 struct vif_params *params
8792 )
8793{
8794 struct wireless_dev *wdev;
8795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008796 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008797 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008798 tCsrRoamProfile *pRoamProfile = NULL;
8799 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308800 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 eMib_dot11DesiredBssType connectedBssType;
8802 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308803 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008804
8805 ENTER();
8806
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308807 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008808 {
8809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8810 "%s: Adapter context is null", __func__);
8811 return VOS_STATUS_E_FAILURE;
8812 }
8813
8814 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8815 if (!pHddCtx)
8816 {
8817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8818 "%s: HDD context is null", __func__);
8819 return VOS_STATUS_E_FAILURE;
8820 }
8821
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308822 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8823 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8824 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308825 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308826 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308828 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 }
8830
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8832 __func__, hdd_device_modetoString(pAdapter->device_mode),
8833 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008834
Agarwal Ashish51325b52014-06-16 16:50:49 +05308835 if (vos_max_concurrent_connections_reached()) {
8836 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8837 return -EINVAL;
8838 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308839 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 wdev = ndev->ieee80211_ptr;
8841
8842#ifdef WLAN_BTAMP_FEATURE
8843 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8844 (NL80211_IFTYPE_ADHOC == type)||
8845 (NL80211_IFTYPE_AP == type)||
8846 (NL80211_IFTYPE_P2P_GO == type))
8847 {
8848 pHddCtx->isAmpAllowed = VOS_FALSE;
8849 // stop AMP traffic
8850 status = WLANBAP_StopAmp();
8851 if(VOS_STATUS_SUCCESS != status )
8852 {
8853 pHddCtx->isAmpAllowed = VOS_TRUE;
8854 hddLog(VOS_TRACE_LEVEL_FATAL,
8855 "%s: Failed to stop AMP", __func__);
8856 return -EINVAL;
8857 }
8858 }
8859#endif //WLAN_BTAMP_FEATURE
8860 /* Reset the current device mode bit mask*/
8861 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8862
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308863 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8864 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8865 (type == NL80211_IFTYPE_P2P_GO)))
8866 {
8867 /* Notify Mode change in case of concurrency.
8868 * Below function invokes TDLS teardown Functionality Since TDLS is
8869 * not Supported in case of concurrency i.e Once P2P session
8870 * is detected disable offchannel and teardown TDLS links
8871 */
8872 hddLog(LOG1,
8873 FL("Device mode = %d Interface type = %d"),
8874 pAdapter->device_mode, type);
8875 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8876 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308877
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008880 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 )
8882 {
8883 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008884 if (!pWextState)
8885 {
8886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8887 "%s: pWextState is null", __func__);
8888 return VOS_STATUS_E_FAILURE;
8889 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 pRoamProfile = &pWextState->roamProfile;
8891 LastBSSType = pRoamProfile->BSSType;
8892
8893 switch (type)
8894 {
8895 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 hddLog(VOS_TRACE_LEVEL_INFO,
8898 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8899 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008900#ifdef WLAN_FEATURE_11AC
8901 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8902 {
8903 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8904 }
8905#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308906 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008907 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008909 //Check for sub-string p2p to confirm its a p2p interface
8910 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308911 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308912#ifdef FEATURE_WLAN_TDLS
8913 mutex_lock(&pHddCtx->tdls_lock);
8914 wlan_hdd_tdls_exit(pAdapter, TRUE);
8915 mutex_unlock(&pHddCtx->tdls_lock);
8916#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008917 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8918 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8919 }
8920 else
8921 {
8922 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308926
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 case NL80211_IFTYPE_ADHOC:
8928 hddLog(VOS_TRACE_LEVEL_INFO,
8929 "%s: setting interface Type to ADHOC", __func__);
8930 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8931 pRoamProfile->phyMode =
8932 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008933 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308935 hdd_set_ibss_ops( pAdapter );
8936 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308937
8938 status = hdd_sta_id_hash_attach(pAdapter);
8939 if (VOS_STATUS_SUCCESS != status) {
8940 hddLog(VOS_TRACE_LEVEL_ERROR,
8941 FL("Failed to initialize hash for IBSS"));
8942 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 break;
8944
8945 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 {
8948 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8949 "%s: setting interface Type to %s", __func__,
8950 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8951
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008952 //Cancel any remain on channel for GO mode
8953 if (NL80211_IFTYPE_P2P_GO == type)
8954 {
8955 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8956 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008957 if (NL80211_IFTYPE_AP == type)
8958 {
8959 /* As Loading WLAN Driver one interface being created for p2p device
8960 * address. This will take one HW STA and the max number of clients
8961 * that can connect to softAP will be reduced by one. so while changing
8962 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8963 * interface as it is not required in SoftAP mode.
8964 */
8965
8966 // Get P2P Adapter
8967 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8968
8969 if (pP2pAdapter)
8970 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308971 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308972 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008973 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8974 }
8975 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308976 //Disable IMPS & BMPS for SAP/GO
8977 if(VOS_STATUS_E_FAILURE ==
8978 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8979 {
8980 //Fail to Exit BMPS
8981 VOS_ASSERT(0);
8982 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308983
8984 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8985
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308986#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008987
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308988 /* A Mutex Lock is introduced while changing the mode to
8989 * protect the concurrent access for the Adapters by TDLS
8990 * module.
8991 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308992 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308993#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308995 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8998 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308999#ifdef FEATURE_WLAN_TDLS
9000 mutex_unlock(&pHddCtx->tdls_lock);
9001#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009002 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
9003 (pConfig->apRandomBssidEnabled))
9004 {
9005 /* To meet Android requirements create a randomized
9006 MAC address of the form 02:1A:11:Fx:xx:xx */
9007 get_random_bytes(&ndev->dev_addr[3], 3);
9008 ndev->dev_addr[0] = 0x02;
9009 ndev->dev_addr[1] = 0x1A;
9010 ndev->dev_addr[2] = 0x11;
9011 ndev->dev_addr[3] |= 0xF0;
9012 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9013 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009014 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9015 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009016 }
9017
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 hdd_set_ap_ops( pAdapter->dev );
9019
Kiet Lam10841362013-11-01 11:36:50 +05309020 /* This is for only SAP mode where users can
9021 * control country through ini.
9022 * P2P GO follows station country code
9023 * acquired during the STA scanning. */
9024 if((NL80211_IFTYPE_AP == type) &&
9025 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9026 {
9027 int status = 0;
9028 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9029 "%s: setting country code from INI ", __func__);
9030 init_completion(&pAdapter->change_country_code);
9031 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9032 (void *)(tSmeChangeCountryCallback)
9033 wlan_hdd_change_country_code_cb,
9034 pConfig->apCntryCode, pAdapter,
9035 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309036 eSIR_FALSE,
9037 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309038 if (eHAL_STATUS_SUCCESS == status)
9039 {
9040 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309041 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309042 &pAdapter->change_country_code,
9043 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309044 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309045 {
9046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309047 FL("SME Timed out while setting country code %ld"),
9048 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009049
9050 if (pHddCtx->isLogpInProgress)
9051 {
9052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9053 "%s: LOGP in Progress. Ignore!!!", __func__);
9054 return -EAGAIN;
9055 }
Kiet Lam10841362013-11-01 11:36:50 +05309056 }
9057 }
9058 else
9059 {
9060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009061 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309062 return -EINVAL;
9063 }
9064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 status = hdd_init_ap_mode(pAdapter);
9066 if(status != VOS_STATUS_SUCCESS)
9067 {
9068 hddLog(VOS_TRACE_LEVEL_FATAL,
9069 "%s: Error initializing the ap mode", __func__);
9070 return -EINVAL;
9071 }
9072 hdd_set_conparam(1);
9073
Nirav Shah7e3c8132015-06-22 23:51:42 +05309074 status = hdd_sta_id_hash_attach(pAdapter);
9075 if (VOS_STATUS_SUCCESS != status)
9076 {
9077 hddLog(VOS_TRACE_LEVEL_ERROR,
9078 FL("Failed to initialize hash for AP"));
9079 return -EINVAL;
9080 }
9081
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 /*interface type changed update in wiphy structure*/
9083 if(wdev)
9084 {
9085 wdev->iftype = type;
9086 pHddCtx->change_iface = type;
9087 }
9088 else
9089 {
9090 hddLog(VOS_TRACE_LEVEL_ERROR,
9091 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9092 return -EINVAL;
9093 }
9094 goto done;
9095 }
9096
9097 default:
9098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9099 __func__);
9100 return -EOPNOTSUPP;
9101 }
9102 }
9103 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 )
9106 {
9107 switch(type)
9108 {
9109 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309112
9113 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309114#ifdef FEATURE_WLAN_TDLS
9115
9116 /* A Mutex Lock is introduced while changing the mode to
9117 * protect the concurrent access for the Adapters by TDLS
9118 * module.
9119 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309120 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309121#endif
c_hpothu002231a2015-02-05 14:58:51 +05309122 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009124 //Check for sub-string p2p to confirm its a p2p interface
9125 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009126 {
9127 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9128 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9129 }
9130 else
9131 {
9132 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009134 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 hdd_set_conparam(0);
9136 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9138 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309139#ifdef FEATURE_WLAN_TDLS
9140 mutex_unlock(&pHddCtx->tdls_lock);
9141#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309142 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 if( VOS_STATUS_SUCCESS != status )
9144 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009145 /* In case of JB, for P2P-GO, only change interface will be called,
9146 * This is the right place to enable back bmps_imps()
9147 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309148 if (pHddCtx->hdd_wlan_suspended)
9149 {
9150 hdd_set_pwrparams(pHddCtx);
9151 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009152 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 goto done;
9154 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9158 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 goto done;
9160 default:
9161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9162 __func__);
9163 return -EOPNOTSUPP;
9164
9165 }
9166
9167 }
9168 else
9169 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309170 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9171 __func__, hdd_device_modetoString(pAdapter->device_mode),
9172 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009173 return -EOPNOTSUPP;
9174 }
9175
9176
9177 if(pRoamProfile)
9178 {
9179 if ( LastBSSType != pRoamProfile->BSSType )
9180 {
9181 /*interface type changed update in wiphy structure*/
9182 wdev->iftype = type;
9183
9184 /*the BSS mode changed, We need to issue disconnect
9185 if connected or in IBSS disconnect state*/
9186 if ( hdd_connGetConnectedBssType(
9187 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9188 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9189 {
9190 /*need to issue a disconnect to CSR.*/
9191 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9192 if( eHAL_STATUS_SUCCESS ==
9193 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9194 pAdapter->sessionId,
9195 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9196 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309197 ret = wait_for_completion_interruptible_timeout(
9198 &pAdapter->disconnect_comp_var,
9199 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9200 if (ret <= 0)
9201 {
9202 hddLog(VOS_TRACE_LEVEL_ERROR,
9203 FL("wait on disconnect_comp_var failed %ld"), ret);
9204 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 }
9206 }
9207 }
9208 }
9209
9210done:
9211 /*set bitmask based on updated value*/
9212 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009213
9214 /* Only STA mode support TM now
9215 * all other mode, TM feature should be disabled */
9216 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9217 (~VOS_STA & pHddCtx->concurrency_mode) )
9218 {
9219 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9220 }
9221
Jeff Johnson295189b2012-06-20 16:38:30 -07009222#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309223 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309224 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 {
9226 //we are ok to do AMP
9227 pHddCtx->isAmpAllowed = VOS_TRUE;
9228 }
9229#endif //WLAN_BTAMP_FEATURE
9230 EXIT();
9231 return 0;
9232}
9233
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309234/*
9235 * FUNCTION: wlan_hdd_cfg80211_change_iface
9236 * wrapper function to protect the actual implementation from SSR.
9237 */
9238int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9239 struct net_device *ndev,
9240 enum nl80211_iftype type,
9241 u32 *flags,
9242 struct vif_params *params
9243 )
9244{
9245 int ret;
9246
9247 vos_ssr_protect(__func__);
9248 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9249 vos_ssr_unprotect(__func__);
9250
9251 return ret;
9252}
9253
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009254#ifdef FEATURE_WLAN_TDLS
9255static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309256 struct net_device *dev,
9257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9258 const u8 *mac,
9259#else
9260 u8 *mac,
9261#endif
9262 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009263{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009264 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009265 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309266 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309267 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309268 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309269 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009270
9271 ENTER();
9272
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309273 if (!dev) {
9274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9275 return -EINVAL;
9276 }
9277
9278 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9279 if (!pAdapter) {
9280 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9281 return -EINVAL;
9282 }
9283
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309284 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009285 {
9286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9287 "Invalid arguments");
9288 return -EINVAL;
9289 }
Hoonki Lee27511902013-03-14 18:19:06 -07009290
9291 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9292 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9293 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009295 "%s: TDLS mode is disabled OR not enabled in FW."
9296 MAC_ADDRESS_STR " Request declined.",
9297 __func__, MAC_ADDR_ARRAY(mac));
9298 return -ENOTSUPP;
9299 }
9300
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009301 if (pHddCtx->isLogpInProgress)
9302 {
9303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9304 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309305 wlan_hdd_tdls_set_link_status(pAdapter,
9306 mac,
9307 eTDLS_LINK_IDLE,
9308 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009309 return -EBUSY;
9310 }
9311
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309312 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309313 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009314
9315 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009317 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9318 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309319 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009320 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009321 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309322 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009323
9324 /* in add station, we accept existing valid staId if there is */
9325 if ((0 == update) &&
9326 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9327 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009328 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009330 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009331 " link_status %d. staId %d. add station ignored.",
9332 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9333 return 0;
9334 }
9335 /* in change station, we accept only when staId is valid */
9336 if ((1 == update) &&
9337 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9338 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9339 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009341 "%s: " MAC_ADDRESS_STR
9342 " link status %d. staId %d. change station %s.",
9343 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9344 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9345 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009346 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009347
9348 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309349 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009350 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9352 "%s: " MAC_ADDRESS_STR
9353 " TDLS setup is ongoing. Request declined.",
9354 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009355 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009356 }
9357
9358 /* first to check if we reached to maximum supported TDLS peer.
9359 TODO: for now, return -EPERM looks working fine,
9360 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309361 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9362 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009363 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9365 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309366 " TDLS Max peer already connected. Request declined."
9367 " Num of peers (%d), Max allowed (%d).",
9368 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9369 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009370 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009371 }
9372 else
9373 {
9374 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309375 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009376 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009377 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9379 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9380 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009381 return -EPERM;
9382 }
9383 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009384 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309385 wlan_hdd_tdls_set_link_status(pAdapter,
9386 mac,
9387 eTDLS_LINK_CONNECTING,
9388 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009389
Jeff Johnsond75fe012013-04-06 10:53:06 -07009390 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309391 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009392 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009394 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009395 if(StaParams->htcap_present)
9396 {
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->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009400 "ht_capa->extended_capabilities: %0x",
9401 StaParams->HTCap.extendedHtCapInfo);
9402 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009404 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009406 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009407 if(StaParams->vhtcap_present)
9408 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009410 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9411 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9412 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9413 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009414 {
9415 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009417 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009419 "[%d]: %x ", i, StaParams->supported_rates[i]);
9420 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009421 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309422 else if ((1 == update) && (NULL == StaParams))
9423 {
9424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9425 "%s : update is true, but staParams is NULL. Error!", __func__);
9426 return -EPERM;
9427 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009428
9429 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9430
9431 if (!update)
9432 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309433 /*Before adding sta make sure that device exited from BMPS*/
9434 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9435 {
9436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9437 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9438 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9439 if (status != VOS_STATUS_SUCCESS) {
9440 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9441 }
9442 }
9443
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309444 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009445 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309446 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309447 hddLog(VOS_TRACE_LEVEL_ERROR,
9448 FL("Failed to add TDLS peer STA. Enable Bmps"));
9449 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309450 return -EPERM;
9451 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009452 }
9453 else
9454 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309455 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009456 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309457 if (ret != eHAL_STATUS_SUCCESS) {
9458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9459 return -EPERM;
9460 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009461 }
9462
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009464 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9465
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309466 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009467 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309469 "%s: timeout waiting for tdls add station indication %ld",
9470 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009471 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009472 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309473
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009474 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9475 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009477 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009478 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009479 }
9480
9481 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009482
9483error:
Atul Mittal115287b2014-07-08 13:26:33 +05309484 wlan_hdd_tdls_set_link_status(pAdapter,
9485 mac,
9486 eTDLS_LINK_IDLE,
9487 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009488 return -EPERM;
9489
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009490}
9491#endif
9492
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309493static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9496 const u8 *mac,
9497#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309499#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 struct station_parameters *params)
9501{
9502 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309503 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309504 hdd_context_t *pHddCtx;
9505 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309507 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009508#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009509 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009510 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309511 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009512#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009513
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309514 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309515
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309516 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309517 if ((NULL == pAdapter))
9518 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309520 "invalid adapter ");
9521 return -EINVAL;
9522 }
9523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9525 TRACE_CODE_HDD_CHANGE_STATION,
9526 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309528
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309529 ret = wlan_hdd_validate_context(pHddCtx);
9530 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309531 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309532 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309533 }
9534
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309535 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9536
9537 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009538 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9540 "invalid HDD station context");
9541 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9544
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009545 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9546 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009548 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 WLANTL_STA_AUTHENTICATED);
9552
Gopichand Nakkala29149562013-05-10 21:43:41 +05309553 if (status != VOS_STATUS_SUCCESS)
9554 {
9555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9556 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9557 return -EINVAL;
9558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 }
9560 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009561 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9562 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309563#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009564 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9565 StaParams.capability = params->capability;
9566 StaParams.uapsd_queues = params->uapsd_queues;
9567 StaParams.max_sp = params->max_sp;
9568
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309569 /* Convert (first channel , number of channels) tuple to
9570 * the total list of channels. This goes with the assumption
9571 * that if the first channel is < 14, then the next channels
9572 * are an incremental of 1 else an incremental of 4 till the number
9573 * of channels.
9574 */
9575 if (0 != params->supported_channels_len) {
9576 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9577 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9578 {
9579 int wifi_chan_index;
9580 StaParams.supported_channels[j] = params->supported_channels[i];
9581 wifi_chan_index =
9582 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9583 no_of_channels = params->supported_channels[i+1];
9584 for(k=1; k <= no_of_channels; k++)
9585 {
9586 StaParams.supported_channels[j+1] =
9587 StaParams.supported_channels[j] + wifi_chan_index;
9588 j+=1;
9589 }
9590 }
9591 StaParams.supported_channels_len = j;
9592 }
9593 vos_mem_copy(StaParams.supported_oper_classes,
9594 params->supported_oper_classes,
9595 params->supported_oper_classes_len);
9596 StaParams.supported_oper_classes_len =
9597 params->supported_oper_classes_len;
9598
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009599 if (0 != params->ext_capab_len)
9600 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9601 sizeof(StaParams.extn_capability));
9602
9603 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009604 {
9605 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009606 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009607 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009608
9609 StaParams.supported_rates_len = params->supported_rates_len;
9610
9611 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9612 * The supported_rates array , for all the structures propogating till Add Sta
9613 * to the firmware has to be modified , if the supplicant (ieee80211) is
9614 * modified to send more rates.
9615 */
9616
9617 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9618 */
9619 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9620 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9621
9622 if (0 != StaParams.supported_rates_len) {
9623 int i = 0;
9624 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9625 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009627 "Supported Rates with Length %d", StaParams.supported_rates_len);
9628 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009630 "[%d]: %0x", i, StaParams.supported_rates[i]);
9631 }
9632
9633 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009634 {
9635 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009636 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009637 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009638
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009639 if (0 != params->ext_capab_len ) {
9640 /*Define A Macro : TODO Sunil*/
9641 if ((1<<4) & StaParams.extn_capability[3]) {
9642 isBufSta = 1;
9643 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309644 /* TDLS Channel Switching Support */
9645 if ((1<<6) & StaParams.extn_capability[3]) {
9646 isOffChannelSupported = 1;
9647 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009648 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309649 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9650 &StaParams, isBufSta,
9651 isOffChannelSupported);
9652
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309653 if (VOS_STATUS_SUCCESS != status) {
9654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9655 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9656 return -EINVAL;
9657 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009658 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9659
9660 if (VOS_STATUS_SUCCESS != status) {
9661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9662 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9663 return -EINVAL;
9664 }
9665 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009666#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309667 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009668 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 return status;
9670}
9671
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9673static int wlan_hdd_change_station(struct wiphy *wiphy,
9674 struct net_device *dev,
9675 const u8 *mac,
9676 struct station_parameters *params)
9677#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309678static int wlan_hdd_change_station(struct wiphy *wiphy,
9679 struct net_device *dev,
9680 u8 *mac,
9681 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309682#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309683{
9684 int ret;
9685
9686 vos_ssr_protect(__func__);
9687 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9688 vos_ssr_unprotect(__func__);
9689
9690 return ret;
9691}
9692
Jeff Johnson295189b2012-06-20 16:38:30 -07009693/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309694 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 * This function is used to initialize the key information
9696 */
9697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309698static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009699 struct net_device *ndev,
9700 u8 key_index, bool pairwise,
9701 const u8 *mac_addr,
9702 struct key_params *params
9703 )
9704#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309705static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 struct net_device *ndev,
9707 u8 key_index, const u8 *mac_addr,
9708 struct key_params *params
9709 )
9710#endif
9711{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 tCsrRoamSetKey setKey;
9714 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309715 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009716 v_U32_t roamId= 0xFF;
9717 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 hdd_hostapd_state_t *pHostapdState;
9719 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009720 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309721 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
9723 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9726 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9727 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309728 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9729 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309730 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009731 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309732 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009733 }
9734
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309735 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9736 __func__, hdd_device_modetoString(pAdapter->device_mode),
9737 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
9739 if (CSR_MAX_NUM_KEY <= key_index)
9740 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 key_index);
9743
9744 return -EINVAL;
9745 }
9746
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009747 if (CSR_MAX_KEY_LEN < params->key_len)
9748 {
9749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9750 params->key_len);
9751
9752 return -EINVAL;
9753 }
9754
9755 hddLog(VOS_TRACE_LEVEL_INFO,
9756 "%s: called with key index = %d & key length %d",
9757 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758
9759 /*extract key idx, key len and key*/
9760 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9761 setKey.keyId = key_index;
9762 setKey.keyLength = params->key_len;
9763 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9764
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009765 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 {
9767 case WLAN_CIPHER_SUITE_WEP40:
9768 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9769 break;
9770
9771 case WLAN_CIPHER_SUITE_WEP104:
9772 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9773 break;
9774
9775 case WLAN_CIPHER_SUITE_TKIP:
9776 {
9777 u8 *pKey = &setKey.Key[0];
9778 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9779
9780 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9781
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009782 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009783
9784 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009785 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 |--------------|----------|----------|
9787 <---16bytes---><--8bytes--><--8bytes-->
9788
9789 */
9790 /*Sme expects the 32 bytes key to be in the below order
9791
9792 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009793 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 |--------------|----------|----------|
9795 <---16bytes---><--8bytes--><--8bytes-->
9796 */
9797 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009798 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009799
9800 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009801 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009802
9803 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009804 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009805
9806
9807 break;
9808 }
9809
9810 case WLAN_CIPHER_SUITE_CCMP:
9811 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9812 break;
9813
9814#ifdef FEATURE_WLAN_WAPI
9815 case WLAN_CIPHER_SUITE_SMS4:
9816 {
9817 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9818 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9819 params->key, params->key_len);
9820 return 0;
9821 }
9822#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009823
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009824#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 case WLAN_CIPHER_SUITE_KRK:
9826 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9827 break;
9828#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009829
9830#ifdef WLAN_FEATURE_11W
9831 case WLAN_CIPHER_SUITE_AES_CMAC:
9832 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009833 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009834#endif
9835
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009837 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309839 status = -EOPNOTSUPP;
9840 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842
9843 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9844 __func__, setKey.encType);
9845
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009846 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009847#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9848 (!pairwise)
9849#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009850 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009851#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009852 )
9853 {
9854 /* set group key*/
9855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9856 "%s- %d: setting Broadcast key",
9857 __func__, __LINE__);
9858 setKey.keyDirection = eSIR_RX_ONLY;
9859 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9860 }
9861 else
9862 {
9863 /* set pairwise key*/
9864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9865 "%s- %d: setting pairwise key",
9866 __func__, __LINE__);
9867 setKey.keyDirection = eSIR_TX_RX;
9868 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9869 }
9870 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9871 {
9872 setKey.keyDirection = eSIR_TX_RX;
9873 /*Set the group key*/
9874 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9875 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009876
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009877 if ( 0 != status )
9878 {
9879 hddLog(VOS_TRACE_LEVEL_ERROR,
9880 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309881 status = -EINVAL;
9882 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009883 }
9884 /*Save the keys here and call sme_RoamSetKey for setting
9885 the PTK after peer joins the IBSS network*/
9886 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9887 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309888 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009889 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309890 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9891 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9892 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009894 if( pHostapdState->bssState == BSS_START )
9895 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009896 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9897 vos_status = wlan_hdd_check_ula_done(pAdapter);
9898
9899 if ( vos_status != VOS_STATUS_SUCCESS )
9900 {
9901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9902 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9903 __LINE__, vos_status );
9904
9905 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9906
9907 status = -EINVAL;
9908 goto end;
9909 }
9910
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9912
9913 if ( status != eHAL_STATUS_SUCCESS )
9914 {
9915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9916 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9917 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309918 status = -EINVAL;
9919 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 }
9921 }
9922
9923 /* Saving WEP keys */
9924 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9925 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9926 {
9927 //Save the wep key in ap context. Issue setkey after the BSS is started.
9928 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9929 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9930 }
9931 else
9932 {
9933 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009934 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9936 }
9937 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009938 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9939 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 {
9941 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9942 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9943
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9945 if (!pairwise)
9946#else
9947 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9948#endif
9949 {
9950 /* set group key*/
9951 if (pHddStaCtx->roam_info.deferKeyComplete)
9952 {
9953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9954 "%s- %d: Perform Set key Complete",
9955 __func__, __LINE__);
9956 hdd_PerformRoamSetKeyComplete(pAdapter);
9957 }
9958 }
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9961
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009962 pWextState->roamProfile.Keys.defaultIndex = key_index;
9963
9964
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009965 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 params->key, params->key_len);
9967
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309968
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9970
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309973 __func__, setKey.peerMac[0], setKey.peerMac[1],
9974 setKey.peerMac[2], setKey.peerMac[3],
9975 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 setKey.keyDirection);
9977
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009978 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309979
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009980 if ( vos_status != VOS_STATUS_SUCCESS )
9981 {
9982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9984 __LINE__, vos_status );
9985
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009986 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009987
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009988 status = -EINVAL;
9989 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009990
9991 }
9992
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009993#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309994 /* The supplicant may attempt to set the PTK once pre-authentication
9995 is done. Save the key in the UMAC and include it in the ADD BSS
9996 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009997 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309998 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009999 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010000 hddLog(VOS_TRACE_LEVEL_INFO_MED,
10001 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010002 status = 0;
10003 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010004 }
10005 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
10006 {
10007 hddLog(VOS_TRACE_LEVEL_ERROR,
10008 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010009 status = -EINVAL;
10010 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010011 }
10012#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010013
10014 /* issue set key request to SME*/
10015 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10016 pAdapter->sessionId, &setKey, &roamId );
10017
10018 if ( 0 != status )
10019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10022 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010023 status = -EINVAL;
10024 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 }
10026
10027
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028 /* in case of IBSS as there was no information available about WEP keys during
10029 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10032 !( ( IW_AUTH_KEY_MGMT_802_1X
10033 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10035 )
10036 &&
10037 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10038 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10039 )
10040 )
10041 {
10042 setKey.keyDirection = eSIR_RX_ONLY;
10043 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10044
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 __func__, setKey.peerMac[0], setKey.peerMac[1],
10048 setKey.peerMac[2], setKey.peerMac[3],
10049 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 setKey.keyDirection);
10051
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 pAdapter->sessionId, &setKey, &roamId );
10054
10055 if ( 0 != status )
10056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010057 hddLog(VOS_TRACE_LEVEL_ERROR,
10058 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 __func__, status);
10060 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010061 status = -EINVAL;
10062 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 }
10064 }
10065 }
10066
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010067end:
10068 /* Need to clear any trace of key value in the memory.
10069 * Thus zero out the memory even though it is local
10070 * variable.
10071 */
10072 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010073 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010074 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010075}
10076
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10078static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10079 struct net_device *ndev,
10080 u8 key_index, bool pairwise,
10081 const u8 *mac_addr,
10082 struct key_params *params
10083 )
10084#else
10085static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10086 struct net_device *ndev,
10087 u8 key_index, const u8 *mac_addr,
10088 struct key_params *params
10089 )
10090#endif
10091{
10092 int ret;
10093 vos_ssr_protect(__func__);
10094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10095 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10096 mac_addr, params);
10097#else
10098 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10099 params);
10100#endif
10101 vos_ssr_unprotect(__func__);
10102
10103 return ret;
10104}
10105
Jeff Johnson295189b2012-06-20 16:38:30 -070010106/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010107 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 * This function is used to get the key information
10109 */
10110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010111static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010112 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 const u8 *mac_addr, void *cookie,
10116 void (*callback)(void *cookie, struct key_params*)
10117 )
10118#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010119static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010120 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 struct net_device *ndev,
10122 u8 key_index, const u8 *mac_addr, void *cookie,
10123 void (*callback)(void *cookie, struct key_params*)
10124 )
10125#endif
10126{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010128 hdd_wext_state_t *pWextState = NULL;
10129 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010131 hdd_context_t *pHddCtx;
10132 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
10134 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010136 if (NULL == pAdapter)
10137 {
10138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10139 "%s: HDD adapter is Null", __func__);
10140 return -ENODEV;
10141 }
10142
10143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10144 ret = wlan_hdd_validate_context(pHddCtx);
10145 if (0 != ret)
10146 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010147 return ret;
10148 }
10149
10150 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10151 pRoamProfile = &(pWextState->roamProfile);
10152
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10154 __func__, hdd_device_modetoString(pAdapter->device_mode),
10155 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010156
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 memset(&params, 0, sizeof(params));
10158
10159 if (CSR_MAX_NUM_KEY <= key_index)
10160 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010163 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010164
10165 switch(pRoamProfile->EncryptionType.encryptionType[0])
10166 {
10167 case eCSR_ENCRYPT_TYPE_NONE:
10168 params.cipher = IW_AUTH_CIPHER_NONE;
10169 break;
10170
10171 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10172 case eCSR_ENCRYPT_TYPE_WEP40:
10173 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10174 break;
10175
10176 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10177 case eCSR_ENCRYPT_TYPE_WEP104:
10178 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10179 break;
10180
10181 case eCSR_ENCRYPT_TYPE_TKIP:
10182 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10183 break;
10184
10185 case eCSR_ENCRYPT_TYPE_AES:
10186 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10187 break;
10188
10189 default:
10190 params.cipher = IW_AUTH_CIPHER_NONE;
10191 break;
10192 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010193
c_hpothuaaf19692014-05-17 17:01:48 +053010194 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10195 TRACE_CODE_HDD_CFG80211_GET_KEY,
10196 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010197
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10199 params.seq_len = 0;
10200 params.seq = NULL;
10201 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10202 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010203 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 return 0;
10205}
10206
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10208static int wlan_hdd_cfg80211_get_key(
10209 struct wiphy *wiphy,
10210 struct net_device *ndev,
10211 u8 key_index, bool pairwise,
10212 const u8 *mac_addr, void *cookie,
10213 void (*callback)(void *cookie, struct key_params*)
10214 )
10215#else
10216static int wlan_hdd_cfg80211_get_key(
10217 struct wiphy *wiphy,
10218 struct net_device *ndev,
10219 u8 key_index, const u8 *mac_addr, void *cookie,
10220 void (*callback)(void *cookie, struct key_params*)
10221 )
10222#endif
10223{
10224 int ret;
10225
10226 vos_ssr_protect(__func__);
10227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10228 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10229 mac_addr, cookie, callback);
10230#else
10231 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10232 callback);
10233#endif
10234 vos_ssr_unprotect(__func__);
10235
10236 return ret;
10237}
10238
Jeff Johnson295189b2012-06-20 16:38:30 -070010239/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010240 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010241 * This function is used to delete the key information
10242 */
10243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010244static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010246 u8 key_index,
10247 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 const u8 *mac_addr
10249 )
10250#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010251static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 struct net_device *ndev,
10253 u8 key_index,
10254 const u8 *mac_addr
10255 )
10256#endif
10257{
10258 int status = 0;
10259
10260 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010261 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 //it is observed that this is invalidating peer
10263 //key index whenever re-key is done. This is affecting data link.
10264 //It should be ok to ignore del_key.
10265#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10267 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10269 tCsrRoamSetKey setKey;
10270 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 ENTER();
10273
10274 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10275 __func__,pAdapter->device_mode);
10276
10277 if (CSR_MAX_NUM_KEY <= key_index)
10278 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 key_index);
10281
10282 return -EINVAL;
10283 }
10284
10285 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10286 setKey.keyId = key_index;
10287
10288 if (mac_addr)
10289 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10290 else
10291 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10292
10293 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10294
10295 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010296 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010297 )
10298 {
10299
10300 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010301 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10302 if( pHostapdState->bssState == BSS_START)
10303 {
10304 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010305
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 if ( status != eHAL_STATUS_SUCCESS )
10307 {
10308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10309 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10310 __LINE__, status );
10311 }
10312 }
10313 }
10314 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010315 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 )
10317 {
10318 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10319
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010320 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10321
10322 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010324 __func__, setKey.peerMac[0], setKey.peerMac[1],
10325 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010327 if(pAdapter->sessionCtx.station.conn_info.connState ==
10328 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010330 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010331 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 if ( 0 != status )
10334 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010335 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 "%s: sme_RoamSetKey failure, returned %d",
10337 __func__, status);
10338 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10339 return -EINVAL;
10340 }
10341 }
10342 }
10343#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010344 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 return status;
10346}
10347
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10349static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10350 struct net_device *ndev,
10351 u8 key_index,
10352 bool pairwise,
10353 const u8 *mac_addr
10354 )
10355#else
10356static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10357 struct net_device *ndev,
10358 u8 key_index,
10359 const u8 *mac_addr
10360 )
10361#endif
10362{
10363 int ret;
10364
10365 vos_ssr_protect(__func__);
10366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10367 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10368 mac_addr);
10369#else
10370 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10371#endif
10372 vos_ssr_unprotect(__func__);
10373
10374 return ret;
10375}
10376
Jeff Johnson295189b2012-06-20 16:38:30 -070010377/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010378 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010379 * This function is used to set the default tx key index
10380 */
10381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010382static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010383 struct net_device *ndev,
10384 u8 key_index,
10385 bool unicast, bool multicast)
10386#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010387static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 struct net_device *ndev,
10389 u8 key_index)
10390#endif
10391{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010393 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010394 hdd_wext_state_t *pWextState;
10395 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010396 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010397
10398 ENTER();
10399
Gopichand Nakkala29149562013-05-10 21:43:41 +053010400 if ((NULL == pAdapter))
10401 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010403 "invalid adapter");
10404 return -EINVAL;
10405 }
10406
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010407 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10408 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10409 pAdapter->sessionId, key_index));
10410
Gopichand Nakkala29149562013-05-10 21:43:41 +053010411 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10412 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10413
10414 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10415 {
10416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10417 "invalid Wext state or HDD context");
10418 return -EINVAL;
10419 }
10420
Arif Hussain6d2a3322013-11-17 19:50:10 -080010421 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010423
Jeff Johnson295189b2012-06-20 16:38:30 -070010424 if (CSR_MAX_NUM_KEY <= key_index)
10425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 key_index);
10428
10429 return -EINVAL;
10430 }
10431
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010432 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10433 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010434 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010435 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010436 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010438
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010441 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010443 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010444 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010445 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010446 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010448 {
10449 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010451
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 tCsrRoamSetKey setKey;
10453 v_U32_t roamId= 0xFF;
10454 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455
10456 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 Keys->defaultIndex = (u8)key_index;
10460 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10461 setKey.keyId = key_index;
10462 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010463
10464 vos_mem_copy(&setKey.Key[0],
10465 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010467
Gopichand Nakkala29149562013-05-10 21:43:41 +053010468 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010469
10470 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 &pHddStaCtx->conn_info.bssId[0],
10472 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010473
Gopichand Nakkala29149562013-05-10 21:43:41 +053010474 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10475 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10476 eCSR_ENCRYPT_TYPE_WEP104)
10477 {
10478 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10479 even though ap is configured for WEP-40 encryption. In this canse the key length
10480 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10481 type(104) and switching encryption type to 40*/
10482 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10483 eCSR_ENCRYPT_TYPE_WEP40;
10484 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10485 eCSR_ENCRYPT_TYPE_WEP40;
10486 }
10487
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010488 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010490
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010494
Jeff Johnson295189b2012-06-20 16:38:30 -070010495 if ( 0 != status )
10496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010497 hddLog(VOS_TRACE_LEVEL_ERROR,
10498 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 status);
10500 return -EINVAL;
10501 }
10502 }
10503 }
10504
10505 /* In SoftAp mode setting key direction for default mode */
10506 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10507 {
10508 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10509 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10510 (eCSR_ENCRYPT_TYPE_AES !=
10511 pWextState->roamProfile.EncryptionType.encryptionType[0])
10512 )
10513 {
10514 /* Saving key direction for default key index to TX default */
10515 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10516 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10517 }
10518 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010519 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 return status;
10521}
10522
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10524static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10525 struct net_device *ndev,
10526 u8 key_index,
10527 bool unicast, bool multicast)
10528#else
10529static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10530 struct net_device *ndev,
10531 u8 key_index)
10532#endif
10533{
10534 int ret;
10535 vos_ssr_protect(__func__);
10536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10537 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10538 multicast);
10539#else
10540 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10541#endif
10542 vos_ssr_unprotect(__func__);
10543
10544 return ret;
10545}
10546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547/*
10548 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10549 * This function is used to inform the BSS details to nl80211 interface.
10550 */
10551static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10552 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10553{
10554 struct net_device *dev = pAdapter->dev;
10555 struct wireless_dev *wdev = dev->ieee80211_ptr;
10556 struct wiphy *wiphy = wdev->wiphy;
10557 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10558 int chan_no;
10559 int ie_length;
10560 const char *ie;
10561 unsigned int freq;
10562 struct ieee80211_channel *chan;
10563 int rssi = 0;
10564 struct cfg80211_bss *bss = NULL;
10565
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 if( NULL == pBssDesc )
10567 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010568 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 return bss;
10570 }
10571
10572 chan_no = pBssDesc->channelId;
10573 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10574 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10575
10576 if( NULL == ie )
10577 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010578 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 return bss;
10580 }
10581
10582#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10583 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10584 {
10585 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10586 }
10587 else
10588 {
10589 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10590 }
10591#else
10592 freq = ieee80211_channel_to_frequency(chan_no);
10593#endif
10594
10595 chan = __ieee80211_get_channel(wiphy, freq);
10596
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010597 if (!chan) {
10598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10599 return NULL;
10600 }
10601
Abhishek Singhaee43942014-06-16 18:55:47 +053010602 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010603
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010604 return cfg80211_inform_bss(wiphy, chan,
10605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10606 CFG80211_BSS_FTYPE_UNKNOWN,
10607#endif
10608 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010609 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 pBssDesc->capabilityInfo,
10611 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010612 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010613}
10614
10615
10616
10617/*
10618 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10619 * This function is used to inform the BSS details to nl80211 interface.
10620 */
10621struct cfg80211_bss*
10622wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10623 tSirBssDescription *bss_desc
10624 )
10625{
10626 /*
10627 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10628 already exists in bss data base of cfg80211 for that particular BSS ID.
10629 Using cfg80211_inform_bss_frame to update the bss entry instead of
10630 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10631 now there is no possibility to get the mgmt(probe response) frame from PE,
10632 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10633 cfg80211_inform_bss_frame.
10634 */
10635 struct net_device *dev = pAdapter->dev;
10636 struct wireless_dev *wdev = dev->ieee80211_ptr;
10637 struct wiphy *wiphy = wdev->wiphy;
10638 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010639#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10640 qcom_ie_age *qie_age = NULL;
10641 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10642#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010643 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010644#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010645 const char *ie =
10646 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10647 unsigned int freq;
10648 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010649 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 struct cfg80211_bss *bss_status = NULL;
10651 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10652 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010653 hdd_context_t *pHddCtx;
10654 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010655#ifdef WLAN_OPEN_SOURCE
10656 struct timespec ts;
10657#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010659
Wilson Yangf80a0542013-10-07 13:02:37 -070010660 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10661 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010662 if (0 != status)
10663 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010664 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010665 }
10666
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010667 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010668 if (!mgmt)
10669 {
10670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10671 "%s: memory allocation failed ", __func__);
10672 return NULL;
10673 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010674
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010676
10677#ifdef WLAN_OPEN_SOURCE
10678 /* Android does not want the timestamp from the frame.
10679 Instead it wants a monotonic increasing value */
10680 get_monotonic_boottime(&ts);
10681 mgmt->u.probe_resp.timestamp =
10682 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10683#else
10684 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10686 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010687
10688#endif
10689
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10691 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010692
10693#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10694 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10695 /* Assuming this is the last IE, copy at the end */
10696 ie_length -=sizeof(qcom_ie_age);
10697 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10698 qie_age->element_id = QCOM_VENDOR_IE_ID;
10699 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10700 qie_age->oui_1 = QCOM_OUI1;
10701 qie_age->oui_2 = QCOM_OUI2;
10702 qie_age->oui_3 = QCOM_OUI3;
10703 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10704 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10705#endif
10706
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010708 if (bss_desc->fProbeRsp)
10709 {
10710 mgmt->frame_control |=
10711 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10712 }
10713 else
10714 {
10715 mgmt->frame_control |=
10716 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10717 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010718
10719#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010720 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10722 {
10723 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10724 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010725 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10727
10728 {
10729 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10730 }
10731 else
10732 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10734 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010735 kfree(mgmt);
10736 return NULL;
10737 }
10738#else
10739 freq = ieee80211_channel_to_frequency(chan_no);
10740#endif
10741 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010742 /*when the band is changed on the fly using the GUI, three things are done
10743 * 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)
10744 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10745 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10746 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10747 * and discards the channels correponding to previous band and calls back with zero bss results.
10748 * 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
10749 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10750 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10751 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10752 * So drop the bss and continue to next bss.
10753 */
10754 if(chan == NULL)
10755 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010757 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010758 return NULL;
10759 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010760 /*To keep the rssi icon of the connected AP in the scan window
10761 *and the rssi icon of the wireless networks in sync
10762 * */
10763 if (( eConnectionState_Associated ==
10764 pAdapter->sessionCtx.station.conn_info.connState ) &&
10765 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10766 pAdapter->sessionCtx.station.conn_info.bssId,
10767 WNI_CFG_BSSID_LEN)) &&
10768 (pHddCtx->hdd_wlan_suspended == FALSE))
10769 {
10770 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10771 rssi = (pAdapter->rssi * 100);
10772 }
10773 else
10774 {
10775 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10776 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010777
Nirav Shah20ac06f2013-12-12 18:14:06 +053010778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010779 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10780 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010781
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10783 frame_len, rssi, GFP_KERNEL);
10784 kfree(mgmt);
10785 return bss_status;
10786}
10787
10788/*
10789 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10790 * This function is used to update the BSS data base of CFG8011
10791 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010792struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010793 tCsrRoamInfo *pRoamInfo
10794 )
10795{
10796 tCsrRoamConnectedProfile roamProfile;
10797 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10798 struct cfg80211_bss *bss = NULL;
10799
10800 ENTER();
10801
10802 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10803 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10804
10805 if (NULL != roamProfile.pBssDesc)
10806 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010807 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10808 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010809
10810 if (NULL == bss)
10811 {
10812 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10813 __func__);
10814 }
10815
10816 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10817 }
10818 else
10819 {
10820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10821 __func__);
10822 }
10823 return bss;
10824}
10825
10826/*
10827 * FUNCTION: wlan_hdd_cfg80211_update_bss
10828 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010829static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10830 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010832{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010833 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010834 tCsrScanResultInfo *pScanResult;
10835 eHalStatus status = 0;
10836 tScanResultHandle pResult;
10837 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010838 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010839 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010841
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010842 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10843 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10844 NO_SESSION, pAdapter->sessionId));
10845
Wilson Yangf80a0542013-10-07 13:02:37 -070010846 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10847
10848 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10851 "%s:LOGP in Progress. Ignore!!!",__func__);
10852 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010853 }
10854
Wilson Yangf80a0542013-10-07 13:02:37 -070010855
10856 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010857 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010858 {
10859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10860 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10861 return VOS_STATUS_E_PERM;
10862 }
10863
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010864 if (pAdapter->request != NULL)
10865 {
10866 if ((pAdapter->request->n_ssids == 1)
10867 && (pAdapter->request->ssids != NULL)
10868 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10869 is_p2p_scan = true;
10870 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 /*
10872 * start getting scan results and populate cgf80211 BSS database
10873 */
10874 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10875
10876 /* no scan results */
10877 if (NULL == pResult)
10878 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010879 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10880 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010881 wlan_hdd_get_frame_logs(pAdapter,
10882 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 return status;
10884 }
10885
10886 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10887
10888 while (pScanResult)
10889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010890 /*
10891 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10892 * entry already exists in bss data base of cfg80211 for that
10893 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10894 * bss entry instead of cfg80211_inform_bss, But this call expects
10895 * mgmt packet as input. As of now there is no possibility to get
10896 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 * ieee80211_mgmt(probe response) and passing to c
10898 * fg80211_inform_bss_frame.
10899 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010900 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10901 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10902 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010903 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10904 continue; //Skip the non p2p bss entries
10905 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10907 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010908
Jeff Johnson295189b2012-06-20 16:38:30 -070010909
10910 if (NULL == bss_status)
10911 {
10912 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010913 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 }
10915 else
10916 {
Yue Maf49ba872013-08-19 12:04:25 -070010917 cfg80211_put_bss(
10918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10919 wiphy,
10920#endif
10921 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 }
10923
10924 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10925 }
10926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010928 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010929 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010930}
10931
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010932void
10933hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10934{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010935 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010936 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010937} /****** end hddPrintMacAddr() ******/
10938
10939void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010940hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010941{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010942 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010943 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010944 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10945 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10946 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010947} /****** end hddPrintPmkId() ******/
10948
10949//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10950//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10951
10952//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10953//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10954
10955#define dump_bssid(bssid) \
10956 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010957 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10958 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010959 }
10960
10961#define dump_pmkid(pMac, pmkid) \
10962 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010963 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10964 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010965 }
10966
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010967#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010968/*
10969 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10970 * This function is used to notify the supplicant of a new PMKSA candidate.
10971 */
10972int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010973 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010974 int index, bool preauth )
10975{
Jeff Johnsone7245742012-09-05 17:12:55 -070010976#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010977 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010978 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010979
10980 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010981 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010982
10983 if( NULL == pRoamInfo )
10984 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010985 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010986 return -EINVAL;
10987 }
10988
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010989 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10990 {
10991 dump_bssid(pRoamInfo->bssid);
10992 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010993 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010994 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010995#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010996 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010997}
10998#endif //FEATURE_WLAN_LFR
10999
Yue Maef608272013-04-08 23:09:17 -070011000#ifdef FEATURE_WLAN_LFR_METRICS
11001/*
11002 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
11003 * 802.11r/LFR metrics reporting function to report preauth initiation
11004 *
11005 */
11006#define MAX_LFR_METRICS_EVENT_LENGTH 100
11007VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
11008 tCsrRoamInfo *pRoamInfo)
11009{
11010 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11011 union iwreq_data wrqu;
11012
11013 ENTER();
11014
11015 if (NULL == pAdapter)
11016 {
11017 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11018 return VOS_STATUS_E_FAILURE;
11019 }
11020
11021 /* create the event */
11022 memset(&wrqu, 0, sizeof(wrqu));
11023 memset(metrics_notification, 0, sizeof(metrics_notification));
11024
11025 wrqu.data.pointer = metrics_notification;
11026 wrqu.data.length = scnprintf(metrics_notification,
11027 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11028 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11029
11030 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11031
11032 EXIT();
11033
11034 return VOS_STATUS_SUCCESS;
11035}
11036
11037/*
11038 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11039 * 802.11r/LFR metrics reporting function to report preauth completion
11040 * or failure
11041 */
11042VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11043 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11044{
11045 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11046 union iwreq_data wrqu;
11047
11048 ENTER();
11049
11050 if (NULL == pAdapter)
11051 {
11052 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11053 return VOS_STATUS_E_FAILURE;
11054 }
11055
11056 /* create the event */
11057 memset(&wrqu, 0, sizeof(wrqu));
11058 memset(metrics_notification, 0, sizeof(metrics_notification));
11059
11060 scnprintf(metrics_notification, sizeof(metrics_notification),
11061 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11062 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11063
11064 if (1 == preauth_status)
11065 strncat(metrics_notification, " TRUE", 5);
11066 else
11067 strncat(metrics_notification, " FALSE", 6);
11068
11069 wrqu.data.pointer = metrics_notification;
11070 wrqu.data.length = strlen(metrics_notification);
11071
11072 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11073
11074 EXIT();
11075
11076 return VOS_STATUS_SUCCESS;
11077}
11078
11079/*
11080 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11081 * 802.11r/LFR metrics reporting function to report handover initiation
11082 *
11083 */
11084VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11085 tCsrRoamInfo *pRoamInfo)
11086{
11087 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11088 union iwreq_data wrqu;
11089
11090 ENTER();
11091
11092 if (NULL == pAdapter)
11093 {
11094 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11095 return VOS_STATUS_E_FAILURE;
11096 }
11097
11098 /* create the event */
11099 memset(&wrqu, 0, sizeof(wrqu));
11100 memset(metrics_notification, 0, sizeof(metrics_notification));
11101
11102 wrqu.data.pointer = metrics_notification;
11103 wrqu.data.length = scnprintf(metrics_notification,
11104 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11105 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11106
11107 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11108
11109 EXIT();
11110
11111 return VOS_STATUS_SUCCESS;
11112}
11113#endif
11114
Jeff Johnson295189b2012-06-20 16:38:30 -070011115/*
11116 * FUNCTION: hdd_cfg80211_scan_done_callback
11117 * scanning callback function, called after finishing scan
11118 *
11119 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11122{
11123 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011124 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011126 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011127 struct cfg80211_scan_request *req = NULL;
11128 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011129 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011130 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011131 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011132 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011133
11134 ENTER();
11135
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011136 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011137 if (NULL == pHddCtx) {
11138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011139 goto allow_suspend;
11140 }
11141
11142 pScanInfo = &pHddCtx->scan_info;
11143
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 hddLog(VOS_TRACE_LEVEL_INFO,
11145 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011146 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 __func__, halHandle, pContext, (int) scanId, (int) status);
11148
Kiet Lamac06e2c2013-10-23 16:25:07 +053011149 pScanInfo->mScanPendingCounter = 0;
11150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011152 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011153 &pScanInfo->scan_req_completion_event,
11154 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011155 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011156 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011157 hddLog(VOS_TRACE_LEVEL_ERROR,
11158 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011160 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 }
11162
Yue Maef608272013-04-08 23:09:17 -070011163 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 {
11165 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011166 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 }
11168
11169 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011170 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011171 {
11172 hddLog(VOS_TRACE_LEVEL_INFO,
11173 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011174 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 (int) scanId);
11176 }
11177
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 pAdapter);
11180
11181 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011183
11184
11185 /* If any client wait scan result through WEXT
11186 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011187 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 {
11189 /* The other scan request waiting for current scan finish
11190 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011191 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011193 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 }
11195 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011196 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 {
11198 struct net_device *dev = pAdapter->dev;
11199 union iwreq_data wrqu;
11200 int we_event;
11201 char *msg;
11202
11203 memset(&wrqu, '\0', sizeof(wrqu));
11204 we_event = SIOCGIWSCAN;
11205 msg = NULL;
11206 wireless_send_event(dev, we_event, &wrqu, msg);
11207 }
11208 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011209 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011210
11211 /* Get the Scan Req */
11212 req = pAdapter->request;
11213
11214 if (!req)
11215 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011216 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011217 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011218 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 }
11220
Jeff Johnson295189b2012-06-20 16:38:30 -070011221 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011222 /* Scan is no longer pending */
11223 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011224
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011225 /* last_scan_timestamp is used to decide if new scan
11226 * is needed or not on station interface. If last station
11227 * scan time and new station scan time is less then
11228 * last_scan_timestamp ; driver will return cached scan.
11229 */
11230 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11231 {
11232 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11233
11234 if ( req->n_channels )
11235 {
11236 for (i = 0; i < req->n_channels ; i++ )
11237 {
11238 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11239 }
11240 /* store no of channel scanned */
11241 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11242 }
11243
11244 }
11245
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011246 /*
11247 * cfg80211_scan_done informing NL80211 about completion
11248 * of scanning
11249 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011250 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11251 {
11252 aborted = true;
11253 }
11254 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011255 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
Siddharth Bhal76972212014-10-15 16:22:51 +053011257 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11258 /* Generate new random mac addr for next scan */
11259 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11260 hdd_processSpoofMacAddrRequest(pHddCtx);
11261 }
11262
Jeff Johnsone7245742012-09-05 17:12:55 -070011263allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011264 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011265 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011266
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011267 /* Acquire wakelock to handle the case where APP's tries to suspend
11268 * immediatly after the driver gets connect request(i.e after scan)
11269 * from supplicant, this result in app's is suspending and not able
11270 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011271 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011272
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011273#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011274 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011275#endif
11276
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 EXIT();
11278 return 0;
11279}
11280
11281/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011282 * FUNCTION: hdd_isConnectionInProgress
11283 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011284 *
11285 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011286v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011287{
11288 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11289 hdd_station_ctx_t *pHddStaCtx = NULL;
11290 hdd_adapter_t *pAdapter = NULL;
11291 VOS_STATUS status = 0;
11292 v_U8_t staId = 0;
11293 v_U8_t *staMac = NULL;
11294
c_hpothu9b781ba2013-12-30 20:57:45 +053011295 if (TRUE == pHddCtx->btCoexModeSet)
11296 {
11297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011298 FL("BTCoex Mode operation in progress"));
11299 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011300 }
11301
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11303
11304 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11305 {
11306 pAdapter = pAdapterNode->pAdapter;
11307
11308 if( pAdapter )
11309 {
11310 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011311 "%s: Adapter with device mode %s (%d) exists",
11312 __func__, hdd_device_modetoString(pAdapter->device_mode),
11313 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011314 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011315 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11316 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11317 (eConnectionState_Connecting ==
11318 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11319 {
11320 hddLog(VOS_TRACE_LEVEL_ERROR,
11321 "%s: %p(%d) Connection is in progress", __func__,
11322 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11323 return VOS_TRUE;
11324 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011325 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011326 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011327 {
11328 hddLog(VOS_TRACE_LEVEL_ERROR,
11329 "%s: %p(%d) Reassociation is in progress", __func__,
11330 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11331 return VOS_TRUE;
11332 }
11333 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011334 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11335 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011336 {
11337 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11338 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011339 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011340 {
11341 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11342 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011343 "%s: client " MAC_ADDRESS_STR
11344 " is in the middle of WPS/EAPOL exchange.", __func__,
11345 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011346 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011347 }
11348 }
11349 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11350 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11351 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011352 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11353 ptSapContext pSapCtx = NULL;
11354 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11355 if(pSapCtx == NULL){
11356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11357 FL("psapCtx is NULL"));
11358 return VOS_FALSE;
11359 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011360 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11361 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011362 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11363 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011364 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011365 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011366
11367 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011368 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11369 "middle of WPS/EAPOL exchange.", __func__,
11370 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011371 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011372 }
11373 }
11374 }
11375 }
11376 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11377 pAdapterNode = pNext;
11378 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011379 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011380}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011381
11382/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011383 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 * this scan respond to scan trigger and update cfg80211 scan database
11385 * later, scan dump command can be used to recieve scan results
11386 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011387int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011388#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11389 struct net_device *dev,
11390#endif
11391 struct cfg80211_scan_request *request)
11392{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011393 hdd_adapter_t *pAdapter = NULL;
11394 hdd_context_t *pHddCtx = NULL;
11395 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011396 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 tCsrScanRequest scanRequest;
11398 tANI_U8 *channelList = NULL, i;
11399 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011400 int status;
11401 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011403 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011404 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011405 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011406 v_S7_t rssi=0;
11407 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011408
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011409#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11410 struct net_device *dev = NULL;
11411 if (NULL == request)
11412 {
11413 hddLog(VOS_TRACE_LEVEL_ERROR,
11414 "%s: scan req param null", __func__);
11415 return -EINVAL;
11416 }
11417 dev = request->wdev->netdev;
11418#endif
11419
11420 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11421 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11422 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11423
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 ENTER();
11425
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11427 __func__, hdd_device_modetoString(pAdapter->device_mode),
11428 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011429
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011430 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011431 if (0 != status)
11432 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011433 return status;
11434 }
11435
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011436 if (NULL == pwextBuf)
11437 {
11438 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11439 __func__);
11440 return -EIO;
11441 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011442 cfg_param = pHddCtx->cfg_ini;
11443 pScanInfo = &pHddCtx->scan_info;
11444
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011445 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11446 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11447 {
11448 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11449 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11450 }
11451
Jeff Johnson295189b2012-06-20 16:38:30 -070011452#ifdef WLAN_BTAMP_FEATURE
11453 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011454 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011456 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 "%s: No scanning when AMP is on", __func__);
11458 return -EOPNOTSUPP;
11459 }
11460#endif
11461 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011462 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011464 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011465 "%s: Not scanning on device_mode = %s (%d)",
11466 __func__, hdd_device_modetoString(pAdapter->device_mode),
11467 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 return -EOPNOTSUPP;
11469 }
11470
11471 if (TRUE == pScanInfo->mScanPending)
11472 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011473 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11474 {
11475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11476 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011477 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 }
11479
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011480 // Don't allow scan if PNO scan is going on.
11481 if (pHddCtx->isPnoEnable)
11482 {
11483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11484 FL("pno scan in progress"));
11485 return -EBUSY;
11486 }
11487
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011489 //Channel and action frame is pending
11490 //Otherwise Cancel Remain On Channel and allow Scan
11491 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011492 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011493 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011495 return -EBUSY;
11496 }
11497
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11499 {
11500 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011501 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011503 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11505 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011506 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 "%s: MAX TM Level Scan not allowed", __func__);
11508 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011509 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 }
11511 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11512
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011513 /* Check if scan is allowed at this point of time.
11514 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011515 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011516 {
11517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11518 return -EBUSY;
11519 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011520
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11522
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011523 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11524 * Becasue of this, driver is assuming that this is not wildcard scan and so
11525 * is not aging out the scan results.
11526 */
11527 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011528 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011529 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011531
11532 if ((request->ssids) && (0 < request->n_ssids))
11533 {
11534 tCsrSSIDInfo *SsidInfo;
11535 int j;
11536 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11537 /* Allocate num_ssid tCsrSSIDInfo structure */
11538 SsidInfo = scanRequest.SSIDs.SSIDList =
11539 ( tCsrSSIDInfo *)vos_mem_malloc(
11540 request->n_ssids*sizeof(tCsrSSIDInfo));
11541
11542 if(NULL == scanRequest.SSIDs.SSIDList)
11543 {
11544 hddLog(VOS_TRACE_LEVEL_ERROR,
11545 "%s: memory alloc failed SSIDInfo buffer", __func__);
11546 return -ENOMEM;
11547 }
11548
11549 /* copy all the ssid's and their length */
11550 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11551 {
11552 /* get the ssid length */
11553 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11554 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11555 SsidInfo->SSID.length);
11556 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11557 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11558 j, SsidInfo->SSID.ssId);
11559 }
11560 /* set the scan type to active */
11561 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11562 }
11563 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011564 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011565 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11566 TRACE_CODE_HDD_CFG80211_SCAN,
11567 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 /* set the scan type to active */
11569 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011570 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011571 else
11572 {
11573 /*Set the scan type to default type, in this case it is ACTIVE*/
11574 scanRequest.scanType = pScanInfo->scan_mode;
11575 }
11576 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11577 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011578
11579 /* set BSSType to default type */
11580 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11581
11582 /*TODO: scan the requested channels only*/
11583
11584 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011585 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011587 hddLog(VOS_TRACE_LEVEL_WARN,
11588 "No of Scan Channels exceeded limit: %d", request->n_channels);
11589 request->n_channels = MAX_CHANNEL;
11590 }
11591
11592 hddLog(VOS_TRACE_LEVEL_INFO,
11593 "No of Scan Channels: %d", request->n_channels);
11594
11595
11596 if( request->n_channels )
11597 {
11598 char chList [(request->n_channels*5)+1];
11599 int len;
11600 channelList = vos_mem_malloc( request->n_channels );
11601 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011602 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011603 hddLog(VOS_TRACE_LEVEL_ERROR,
11604 "%s: memory alloc failed channelList", __func__);
11605 status = -ENOMEM;
11606 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011607 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011608
11609 for( i = 0, len = 0; i < request->n_channels ; i++ )
11610 {
11611 channelList[i] = request->channels[i]->hw_value;
11612 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11613 }
11614
Nirav Shah20ac06f2013-12-12 18:14:06 +053011615 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011616 "Channel-List: %s ", chList);
11617 }
c_hpothu53512302014-04-15 18:49:53 +053011618
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011619 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11620 scanRequest.ChannelInfo.ChannelList = channelList;
11621
11622 /* set requestType to full scan */
11623 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11624
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011625 /* if there is back to back scan happening in driver with in
11626 * nDeferScanTimeInterval interval driver should defer new scan request
11627 * and should provide last cached scan results instead of new channel list.
11628 * This rule is not applicable if scan is p2p scan.
11629 * This condition will work only in case when last request no of channels
11630 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011631 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011632 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011633 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011634
Sushant Kaushik86592172015-04-27 16:35:03 +053011635 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11636 /* if wps ie is NULL , then only defer scan */
11637 if ( pWpsIe == NULL &&
11638 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011639 {
11640 if ( pScanInfo->last_scan_timestamp !=0 &&
11641 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11642 {
11643 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11644 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11645 vos_mem_compare(pScanInfo->last_scan_channelList,
11646 channelList, pScanInfo->last_scan_numChannels))
11647 {
11648 hddLog(VOS_TRACE_LEVEL_WARN,
11649 " New and old station scan time differ is less then %u",
11650 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11651
11652 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011653 pAdapter);
11654
Agarwal Ashish57e84372014-12-05 18:26:53 +053011655 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011656 "Return old cached scan as all channels and no of channels are same");
11657
Agarwal Ashish57e84372014-12-05 18:26:53 +053011658 if (0 > ret)
11659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011660
Agarwal Ashish57e84372014-12-05 18:26:53 +053011661 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011662
11663 status = eHAL_STATUS_SUCCESS;
11664 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011665 }
11666 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011667 }
11668
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011669 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11670 * search (Flush on both full scan and social scan but not on single
11671 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11672 */
11673
11674 /* Supplicant does single channel scan after 8-way handshake
11675 * and in that case driver shoudnt flush scan results. If
11676 * driver flushes the scan results here and unfortunately if
11677 * the AP doesnt respond to our probe req then association
11678 * fails which is not desired
11679 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011680 if ((request->n_ssids == 1)
11681 && (request->ssids != NULL)
11682 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11683 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011684
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011685 if( is_p2p_scan ||
11686 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011687 {
11688 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11689 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11690 pAdapter->sessionId );
11691 }
11692
11693 if( request->ie_len )
11694 {
11695 /* save this for future association (join requires this) */
11696 /*TODO: Array needs to be converted to dynamic allocation,
11697 * as multiple ie.s can be sent in cfg80211_scan_request structure
11698 * CR 597966
11699 */
11700 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11701 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11702 pScanInfo->scanAddIE.length = request->ie_len;
11703
11704 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11705 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11706 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011708 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011710 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11711 memcpy( pwextBuf->roamProfile.addIEScan,
11712 request->ie, request->ie_len);
11713 }
11714 else
11715 {
11716 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11717 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 }
11719
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011720 }
11721 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11722 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11723
11724 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11725 request->ie_len);
11726 if (pP2pIe != NULL)
11727 {
11728#ifdef WLAN_FEATURE_P2P_DEBUG
11729 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11730 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11731 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011732 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011733 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11734 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11735 "Go nego completed to Connection is started");
11736 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11737 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011738 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011739 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11740 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011741 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011742 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11743 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11744 "Disconnected state to Connection is started");
11745 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11746 "for 4way Handshake");
11747 }
11748#endif
11749
11750 /* no_cck will be set during p2p find to disable 11b rates */
11751 if(TRUE == request->no_cck)
11752 {
11753 hddLog(VOS_TRACE_LEVEL_INFO,
11754 "%s: This is a P2P Search", __func__);
11755 scanRequest.p2pSearch = 1;
11756
11757 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011758 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011759 /* set requestType to P2P Discovery */
11760 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11761 }
11762
11763 /*
11764 Skip Dfs Channel in case of P2P Search
11765 if it is set in ini file
11766 */
11767 if(cfg_param->skipDfsChnlInP2pSearch)
11768 {
11769 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011770 }
11771 else
11772 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011773 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011774 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011775
Agarwal Ashish4f616132013-12-30 23:32:50 +053011776 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 }
11778 }
11779
11780 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11781
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011782#ifdef FEATURE_WLAN_TDLS
11783 /* if tdls disagree scan right now, return immediately.
11784 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11785 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11786 */
11787 status = wlan_hdd_tdls_scan_callback (pAdapter,
11788 wiphy,
11789#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11790 dev,
11791#endif
11792 request);
11793 if(status <= 0)
11794 {
11795 if(!status)
11796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11797 "scan rejected %d", __func__, status);
11798 else
11799 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11800 __func__, status);
11801
11802 return status;
11803 }
11804#endif
11805
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011806 /* acquire the wakelock to avoid the apps suspend during the scan. To
11807 * address the following issues.
11808 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11809 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11810 * for long time, this result in apps running at full power for long time.
11811 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11812 * be stuck in full power because of resume BMPS
11813 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011814 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011815
Nirav Shah20ac06f2013-12-12 18:14:06 +053011816 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11817 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011818 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11819 scanRequest.requestType, scanRequest.scanType,
11820 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011821 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11822
Siddharth Bhal76972212014-10-15 16:22:51 +053011823 if (pHddCtx->spoofMacAddr.isEnabled)
11824 {
11825 hddLog(VOS_TRACE_LEVEL_INFO,
11826 "%s: MAC Spoofing enabled for current scan", __func__);
11827 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11828 * to fill TxBds for probe request during current scan
11829 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011830 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011831 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011832
11833 if(status != VOS_STATUS_SUCCESS)
11834 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011835 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011836 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011837#ifdef FEATURE_WLAN_TDLS
11838 wlan_hdd_tdls_scan_done_callback(pAdapter);
11839#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011840 goto free_mem;
11841 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011842 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011843 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011844 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 pAdapter->sessionId, &scanRequest, &scanId,
11846 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011847
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 if (eHAL_STATUS_SUCCESS != status)
11849 {
11850 hddLog(VOS_TRACE_LEVEL_ERROR,
11851 "%s: sme_ScanRequest returned error %d", __func__, status);
11852 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011853 if(eHAL_STATUS_RESOURCES == status)
11854 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11856 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011857 status = -EBUSY;
11858 } else {
11859 status = -EIO;
11860 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011861 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011862
11863#ifdef FEATURE_WLAN_TDLS
11864 wlan_hdd_tdls_scan_done_callback(pAdapter);
11865#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 goto free_mem;
11867 }
11868
11869 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011870 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011871 pAdapter->request = request;
11872 pScanInfo->scanId = scanId;
11873
11874 complete(&pScanInfo->scan_req_completion_event);
11875
11876free_mem:
11877 if( scanRequest.SSIDs.SSIDList )
11878 {
11879 vos_mem_free(scanRequest.SSIDs.SSIDList);
11880 }
11881
11882 if( channelList )
11883 vos_mem_free( channelList );
11884
11885 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 return status;
11887}
11888
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011889int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11890#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11891 struct net_device *dev,
11892#endif
11893 struct cfg80211_scan_request *request)
11894{
11895 int ret;
11896
11897 vos_ssr_protect(__func__);
11898 ret = __wlan_hdd_cfg80211_scan(wiphy,
11899#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11900 dev,
11901#endif
11902 request);
11903 vos_ssr_unprotect(__func__);
11904
11905 return ret;
11906}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011907
11908void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11909{
11910 v_U8_t iniDot11Mode =
11911 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11912 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11913
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011914 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11915 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011916 switch ( iniDot11Mode )
11917 {
11918 case eHDD_DOT11_MODE_AUTO:
11919 case eHDD_DOT11_MODE_11ac:
11920 case eHDD_DOT11_MODE_11ac_ONLY:
11921#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011922 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11923 sme_IsFeatureSupportedByFW(DOT11AC) )
11924 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11925 else
11926 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011927#else
11928 hddDot11Mode = eHDD_DOT11_MODE_11n;
11929#endif
11930 break;
11931 case eHDD_DOT11_MODE_11n:
11932 case eHDD_DOT11_MODE_11n_ONLY:
11933 hddDot11Mode = eHDD_DOT11_MODE_11n;
11934 break;
11935 default:
11936 hddDot11Mode = iniDot11Mode;
11937 break;
11938 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011939#ifdef WLAN_FEATURE_AP_HT40_24G
11940 if (operationChannel > SIR_11B_CHANNEL_END)
11941#endif
11942 {
11943 /* This call decides required channel bonding mode */
11944 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011945 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11946 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011947 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011948}
11949
Jeff Johnson295189b2012-06-20 16:38:30 -070011950/*
11951 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011952 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011954int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011955 const u8 *ssid, size_t ssid_len, const u8 *bssid,
11956 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011957{
11958 int status = 0;
11959 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011960 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 v_U32_t roamId;
11962 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053011964 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011965
11966 ENTER();
11967
11968 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011969 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11970
11971 status = wlan_hdd_validate_context(pHddCtx);
11972 if (status)
11973 {
Yue Mae36e3552014-03-05 17:06:20 -080011974 return status;
11975 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11978 {
11979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11980 return -EINVAL;
11981 }
11982
11983 pRoamProfile = &pWextState->roamProfile;
11984
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011985 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011987 hdd_station_ctx_t *pHddStaCtx;
11988 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011989
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011990 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11991
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011992 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11994 {
11995 /*QoS not enabled in cfg file*/
11996 pRoamProfile->uapsd_mask = 0;
11997 }
11998 else
11999 {
12000 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012001 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
12003 }
12004
12005 pRoamProfile->SSIDs.numOfSSIDs = 1;
12006 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
12007 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
12010 ssid, ssid_len);
12011
12012 if (bssid)
12013 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012014 pValidBssid = bssid;
12015 }
12016 else if (bssid_hint)
12017 {
12018 pValidBssid = bssid_hint;
12019 }
12020 if (pValidBssid)
12021 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012023 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012025 /* Save BSSID in seperate variable as well, as RoamProfile
12026 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 case of join failure we should send valid BSSID to supplicant
12028 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012029 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012030 WNI_CFG_BSSID_LEN);
12031 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012032 else
12033 {
12034 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12035 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012036
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012037 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12038 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12040 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012041 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 /*set gen ie*/
12043 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12044 /*set auth*/
12045 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012047#ifdef FEATURE_WLAN_WAPI
12048 if (pAdapter->wapi_info.nWapiMode)
12049 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012050 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012051 switch (pAdapter->wapi_info.wapiAuthMode)
12052 {
12053 case WAPI_AUTH_MODE_PSK:
12054 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012055 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012056 pAdapter->wapi_info.wapiAuthMode);
12057 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12058 break;
12059 }
12060 case WAPI_AUTH_MODE_CERT:
12061 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012062 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012063 pAdapter->wapi_info.wapiAuthMode);
12064 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12065 break;
12066 }
12067 } // End of switch
12068 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12069 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12070 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012071 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 pRoamProfile->AuthType.numEntries = 1;
12073 pRoamProfile->EncryptionType.numEntries = 1;
12074 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12075 pRoamProfile->mcEncryptionType.numEntries = 1;
12076 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12077 }
12078 }
12079#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012080#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012081 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012082 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12083 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12084 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012085 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12086 sizeof (tSirGtkOffloadParams));
12087 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012088 }
12089#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012090 pRoamProfile->csrPersona = pAdapter->device_mode;
12091
Jeff Johnson32d95a32012-09-10 13:15:23 -070012092 if( operatingChannel )
12093 {
12094 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12095 pRoamProfile->ChannelInfo.numOfChannels = 1;
12096 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012097 else
12098 {
12099 pRoamProfile->ChannelInfo.ChannelList = NULL;
12100 pRoamProfile->ChannelInfo.numOfChannels = 0;
12101 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012102 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12103 {
12104 hdd_select_cbmode(pAdapter,operatingChannel);
12105 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012106
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012107 /*
12108 * Change conn_state to connecting before sme_RoamConnect(),
12109 * because sme_RoamConnect() has a direct path to call
12110 * hdd_smeRoamCallback(), which will change the conn_state
12111 * If direct path, conn_state will be accordingly changed
12112 * to NotConnected or Associated by either
12113 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12114 * in sme_RoamCallback()
12115 * if sme_RomConnect is to be queued,
12116 * Connecting state will remain until it is completed.
12117 * If connection state is not changed,
12118 * connection state will remain in eConnectionState_NotConnected state.
12119 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12120 * if conn state is eConnectionState_NotConnected.
12121 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12122 * informed of connect result indication which is an issue.
12123 */
12124
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012125 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12126 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012127 {
12128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012129 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012130 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12131 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012132 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012133 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012134 pAdapter->sessionId, pRoamProfile, &roamId);
12135
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012136 if ((eHAL_STATUS_SUCCESS != status) &&
12137 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12138 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012139
12140 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012141 hddLog(VOS_TRACE_LEVEL_ERROR,
12142 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12143 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012144 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012145 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012146 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012147 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012148
12149 pRoamProfile->ChannelInfo.ChannelList = NULL;
12150 pRoamProfile->ChannelInfo.numOfChannels = 0;
12151
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 }
12153 else
12154 {
12155 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12156 return -EINVAL;
12157 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012158 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 return status;
12160}
12161
12162/*
12163 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12164 * This function is used to set the authentication type (OPEN/SHARED).
12165 *
12166 */
12167static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12168 enum nl80211_auth_type auth_type)
12169{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012170 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12172
12173 ENTER();
12174
12175 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012176 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012179 hddLog(VOS_TRACE_LEVEL_INFO,
12180 "%s: set authentication type to AUTOSWITCH", __func__);
12181 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12182 break;
12183
12184 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012185#ifdef WLAN_FEATURE_VOWIFI_11R
12186 case NL80211_AUTHTYPE_FT:
12187#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 "%s: set authentication type to OPEN", __func__);
12190 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12191 break;
12192
12193 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012194 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 "%s: set authentication type to SHARED", __func__);
12196 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12197 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012198#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 "%s: set authentication type to CCKM WPA", __func__);
12202 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12203 break;
12204#endif
12205
12206
12207 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 hddLog(VOS_TRACE_LEVEL_ERROR,
12209 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 auth_type);
12211 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12212 return -EINVAL;
12213 }
12214
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012215 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 pHddStaCtx->conn_info.authType;
12217 return 0;
12218}
12219
12220/*
12221 * FUNCTION: wlan_hdd_set_akm_suite
12222 * This function is used to set the key mgmt type(PSK/8021x).
12223 *
12224 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012225static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 u32 key_mgmt
12227 )
12228{
12229 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12230 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012231 /* Should be in ieee802_11_defs.h */
12232#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12233#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 /*set key mgmt type*/
12235 switch(key_mgmt)
12236 {
12237 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012238 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012239#ifdef WLAN_FEATURE_VOWIFI_11R
12240 case WLAN_AKM_SUITE_FT_PSK:
12241#endif
12242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 __func__);
12244 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12245 break;
12246
12247 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012248 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012249#ifdef WLAN_FEATURE_VOWIFI_11R
12250 case WLAN_AKM_SUITE_FT_8021X:
12251#endif
12252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 __func__);
12254 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12255 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012256#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012257#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12258#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12259 case WLAN_AKM_SUITE_CCKM:
12260 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12261 __func__);
12262 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12263 break;
12264#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012265#ifndef WLAN_AKM_SUITE_OSEN
12266#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12267 case WLAN_AKM_SUITE_OSEN:
12268 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12269 __func__);
12270 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12271 break;
12272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012273
12274 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 __func__, key_mgmt);
12277 return -EINVAL;
12278
12279 }
12280 return 0;
12281}
12282
12283/*
12284 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012285 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 * (NONE/WEP40/WEP104/TKIP/CCMP).
12287 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012288static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12289 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 bool ucast
12291 )
12292{
12293 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012294 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12296
12297 ENTER();
12298
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012299 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 __func__, cipher);
12303 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12304 }
12305 else
12306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012307
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012309 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 {
12311 case IW_AUTH_CIPHER_NONE:
12312 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12313 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012314
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012316 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012318
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012320 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012322
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 case WLAN_CIPHER_SUITE_TKIP:
12324 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12325 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012326
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 case WLAN_CIPHER_SUITE_CCMP:
12328 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12329 break;
12330#ifdef FEATURE_WLAN_WAPI
12331 case WLAN_CIPHER_SUITE_SMS4:
12332 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12333 break;
12334#endif
12335
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012336#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 case WLAN_CIPHER_SUITE_KRK:
12338 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12339 break;
12340#endif
12341 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 __func__, cipher);
12344 return -EOPNOTSUPP;
12345 }
12346 }
12347
12348 if (ucast)
12349 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 __func__, encryptionType);
12352 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12353 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012354 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 encryptionType;
12356 }
12357 else
12358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012359 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012360 __func__, encryptionType);
12361 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12362 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12363 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12364 }
12365
12366 return 0;
12367}
12368
12369
12370/*
12371 * FUNCTION: wlan_hdd_cfg80211_set_ie
12372 * This function is used to parse WPA/RSN IE's.
12373 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012374int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012375#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12376 const u8 *ie,
12377#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012378 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012380 size_t ie_len
12381 )
12382{
12383 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12385 const u8 *genie = ie;
12386#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012388#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 v_U16_t remLen = ie_len;
12390#ifdef FEATURE_WLAN_WAPI
12391 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12392 u16 *tmp;
12393 v_U16_t akmsuiteCount;
12394 int *akmlist;
12395#endif
12396 ENTER();
12397
12398 /* clear previous assocAddIE */
12399 pWextState->assocAddIE.length = 0;
12400 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012401 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012402
12403 while (remLen >= 2)
12404 {
12405 v_U16_t eLen = 0;
12406 v_U8_t elementId;
12407 elementId = *genie++;
12408 eLen = *genie++;
12409 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012410
Arif Hussain6d2a3322013-11-17 19:50:10 -080012411 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012413
12414 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012417 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 -070012418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012419 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 "%s: Invalid WPA IE", __func__);
12421 return -EINVAL;
12422 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012423 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 {
12425 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012426 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012428
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012429 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012431 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12432 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 VOS_ASSERT(0);
12434 return -ENOMEM;
12435 }
12436 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12437 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12438 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012439
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12441 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12442 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12443 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012444 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12445 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12447 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12448 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12449 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12450 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12451 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012452 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012453 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 {
12455 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012456 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012457 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012458
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012459 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012460 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012461 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12462 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 VOS_ASSERT(0);
12464 return -ENOMEM;
12465 }
12466 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12467 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12468 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012469
Jeff Johnson295189b2012-06-20 16:38:30 -070012470 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12471 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12472 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012473#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012474 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12475 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012476 /*Consider WFD IE, only for P2P Client */
12477 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12478 {
12479 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012482
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012483 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012485 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12486 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 VOS_ASSERT(0);
12488 return -ENOMEM;
12489 }
12490 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12491 // WPS IE + P2P IE + WFD IE
12492 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12493 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012494
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12496 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12497 }
12498#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012499 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012500 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012501 HS20_OUI_TYPE_SIZE)) )
12502 {
12503 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012504 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012505 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012506
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012507 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012508 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012509 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12510 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012511 VOS_ASSERT(0);
12512 return -ENOMEM;
12513 }
12514 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12515 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012516
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012517 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12518 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12519 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012520 /* Appending OSEN Information Element in Assiciation Request */
12521 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12522 OSEN_OUI_TYPE_SIZE)) )
12523 {
12524 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12525 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12526 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012527
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012528 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012529 {
12530 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12531 "Need bigger buffer space");
12532 VOS_ASSERT(0);
12533 return -ENOMEM;
12534 }
12535 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12536 pWextState->assocAddIE.length += eLen + 2;
12537
12538 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12539 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12540 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12541 }
12542
Abhishek Singh4322e622015-06-10 15:42:54 +053012543 /* Update only for WPA IE */
12544 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12545 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012546
12547 /* populating as ADDIE in beacon frames */
12548 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012549 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012550 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12551 {
12552 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12553 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12554 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12555 {
12556 hddLog(LOGE,
12557 "Coldn't pass "
12558 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12559 }
12560 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12561 else
12562 hddLog(LOGE,
12563 "Could not pass on "
12564 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12565
12566 /* IBSS mode doesn't contain params->proberesp_ies still
12567 beaconIE's need to be populated in probe response frames */
12568 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12569 {
12570 u16 rem_probe_resp_ie_len = eLen + 2;
12571 u8 probe_rsp_ie_len[3] = {0};
12572 u8 counter = 0;
12573
12574 /* Check Probe Resp Length if it is greater then 255 then
12575 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12576 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12577 not able Store More then 255 bytes into One Variable */
12578
12579 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12580 {
12581 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12582 {
12583 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12584 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12585 }
12586 else
12587 {
12588 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12589 rem_probe_resp_ie_len = 0;
12590 }
12591 }
12592
12593 rem_probe_resp_ie_len = 0;
12594
12595 if (probe_rsp_ie_len[0] > 0)
12596 {
12597 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12598 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12599 (tANI_U8*)(genie - 2),
12600 probe_rsp_ie_len[0], NULL,
12601 eANI_BOOLEAN_FALSE)
12602 == eHAL_STATUS_FAILURE)
12603 {
12604 hddLog(LOGE,
12605 "Could not pass"
12606 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12607 }
12608 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12609 }
12610
12611 if (probe_rsp_ie_len[1] > 0)
12612 {
12613 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12614 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12615 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12616 probe_rsp_ie_len[1], NULL,
12617 eANI_BOOLEAN_FALSE)
12618 == eHAL_STATUS_FAILURE)
12619 {
12620 hddLog(LOGE,
12621 "Could not pass"
12622 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12623 }
12624 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12625 }
12626
12627 if (probe_rsp_ie_len[2] > 0)
12628 {
12629 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12630 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12631 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12632 probe_rsp_ie_len[2], NULL,
12633 eANI_BOOLEAN_FALSE)
12634 == eHAL_STATUS_FAILURE)
12635 {
12636 hddLog(LOGE,
12637 "Could not pass"
12638 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12639 }
12640 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12641 }
12642
12643 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12644 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12645 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12646 {
12647 hddLog(LOGE,
12648 "Could not pass"
12649 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12650 }
12651 }
12652 else
12653 {
12654 // Reset WNI_CFG_PROBE_RSP Flags
12655 wlan_hdd_reset_prob_rspies(pAdapter);
12656
12657 hddLog(VOS_TRACE_LEVEL_INFO,
12658 "%s: No Probe Response IE received in set beacon",
12659 __func__);
12660 }
12661 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 break;
12663 case DOT11F_EID_RSN:
12664 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12665 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12666 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12667 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12668 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12669 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012670
12671 /* Appending Extended Capabilities with Interworking bit set
12672 * in Assoc Req.
12673 *
12674 * In assoc req this EXT Cap will only be taken into account if
12675 * interworkingService bit is set to 1. Currently
12676 * driver is only interested in interworkingService capability
12677 * from supplicant. If in future any other EXT Cap info is
12678 * required from supplicat, it needs to be handled while
12679 * sending Assoc Req in LIM.
12680 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012681 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012682 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012683 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012684 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012685 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012686
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012687 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012688 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012689 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12690 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012691 VOS_ASSERT(0);
12692 return -ENOMEM;
12693 }
12694 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12695 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012696
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012697 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12698 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12699 break;
12700 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012701#ifdef FEATURE_WLAN_WAPI
12702 case WLAN_EID_WAPI:
12703 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012704 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 pAdapter->wapi_info.nWapiMode);
12706 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012707 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 akmsuiteCount = WPA_GET_LE16(tmp);
12709 tmp = tmp + 1;
12710 akmlist = (int *)(tmp);
12711 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12712 {
12713 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12714 }
12715 else
12716 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012717 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012718 VOS_ASSERT(0);
12719 return -EINVAL;
12720 }
12721
12722 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12723 {
12724 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012725 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012726 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012729 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012731 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12733 }
12734 break;
12735#endif
12736 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012737 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012739 /* when Unknown IE is received we should break and continue
12740 * to the next IE in the buffer instead we were returning
12741 * so changing this to break */
12742 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 }
12744 genie += eLen;
12745 remLen -= eLen;
12746 }
12747 EXIT();
12748 return 0;
12749}
12750
12751/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012752 * FUNCTION: hdd_isWPAIEPresent
12753 * Parse the received IE to find the WPA IE
12754 *
12755 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012756static bool hdd_isWPAIEPresent(
12757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12758 const u8 *ie,
12759#else
12760 u8 *ie,
12761#endif
12762 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012763{
12764 v_U8_t eLen = 0;
12765 v_U16_t remLen = ie_len;
12766 v_U8_t elementId = 0;
12767
12768 while (remLen >= 2)
12769 {
12770 elementId = *ie++;
12771 eLen = *ie++;
12772 remLen -= 2;
12773 if (eLen > remLen)
12774 {
12775 hddLog(VOS_TRACE_LEVEL_ERROR,
12776 "%s: IE length is wrong %d", __func__, eLen);
12777 return FALSE;
12778 }
12779 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12780 {
12781 /* OUI - 0x00 0X50 0XF2
12782 WPA Information Element - 0x01
12783 WPA version - 0x01*/
12784 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12785 return TRUE;
12786 }
12787 ie += eLen;
12788 remLen -= eLen;
12789 }
12790 return FALSE;
12791}
12792
12793/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012794 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012795 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012796 * parameters during connect operation.
12797 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012798int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012800 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012801{
12802 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012803 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 ENTER();
12805
12806 /*set wpa version*/
12807 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12808
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012809 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012810 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012811 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 {
12813 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12814 }
12815 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12816 {
12817 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12818 }
12819 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012820
12821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012822 pWextState->wpaVersion);
12823
12824 /*set authentication type*/
12825 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12826
12827 if (0 > status)
12828 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012829 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012830 "%s: failed to set authentication type ", __func__);
12831 return status;
12832 }
12833
12834 /*set key mgmt type*/
12835 if (req->crypto.n_akm_suites)
12836 {
12837 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12838 if (0 > status)
12839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012840 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 __func__);
12842 return status;
12843 }
12844 }
12845
12846 /*set pairwise cipher type*/
12847 if (req->crypto.n_ciphers_pairwise)
12848 {
12849 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12850 req->crypto.ciphers_pairwise[0], true);
12851 if (0 > status)
12852 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012853 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 "%s: failed to set unicast cipher type", __func__);
12855 return status;
12856 }
12857 }
12858 else
12859 {
12860 /*Reset previous cipher suite to none*/
12861 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12862 if (0 > status)
12863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012864 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 "%s: failed to set unicast cipher type", __func__);
12866 return status;
12867 }
12868 }
12869
12870 /*set group cipher type*/
12871 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12872 false);
12873
12874 if (0 > status)
12875 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 __func__);
12878 return status;
12879 }
12880
Chet Lanctot186b5732013-03-18 10:26:30 -070012881#ifdef WLAN_FEATURE_11W
12882 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12883#endif
12884
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12886 if (req->ie_len)
12887 {
12888 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12889 if ( 0 > status)
12890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 __func__);
12893 return status;
12894 }
12895 }
12896
12897 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 {
12900 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12901 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12902 )
12903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012904 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 __func__);
12909 return -EOPNOTSUPP;
12910 }
12911 else
12912 {
12913 u8 key_len = req->key_len;
12914 u8 key_idx = req->key_idx;
12915
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012916 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012917 && (CSR_MAX_NUM_KEY > key_idx)
12918 )
12919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012920 hddLog(VOS_TRACE_LEVEL_INFO,
12921 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 __func__, key_idx, key_len);
12923 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012926 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012927 (u8)key_len;
12928 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12929 }
12930 }
12931 }
12932 }
12933
12934 return status;
12935}
12936
12937/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012938 * FUNCTION: wlan_hdd_try_disconnect
12939 * This function is used to disconnect from previous
12940 * connection
12941 */
12942static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12943{
12944 long ret = 0;
12945 hdd_station_ctx_t *pHddStaCtx;
12946 eMib_dot11DesiredBssType connectedBssType;
12947
12948 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12949
12950 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12951
12952 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12953 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12954 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12955 {
12956 /* Issue disconnect to CSR */
12957 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12958 if( eHAL_STATUS_SUCCESS ==
12959 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12960 pAdapter->sessionId,
12961 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12962 {
12963 ret = wait_for_completion_interruptible_timeout(
12964 &pAdapter->disconnect_comp_var,
12965 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12966 if (0 >= ret)
12967 {
12968 hddLog(LOGE, FL("Failed to receive disconnect event"));
12969 return -EALREADY;
12970 }
12971 }
12972 }
12973 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12974 {
12975 ret = wait_for_completion_interruptible_timeout(
12976 &pAdapter->disconnect_comp_var,
12977 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12978 if (0 >= ret)
12979 {
12980 hddLog(LOGE, FL("Failed to receive disconnect event"));
12981 return -EALREADY;
12982 }
12983 }
12984
12985 return 0;
12986}
12987
12988/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012989 * FUNCTION: __wlan_hdd_cfg80211_connect
12990 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012992static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 struct net_device *ndev,
12994 struct cfg80211_connect_params *req
12995 )
12996{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012997 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012998 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012999 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053013000 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013001
13002 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013003
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013004 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13005 TRACE_CODE_HDD_CFG80211_CONNECT,
13006 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013007 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013008 "%s: device_mode = %s (%d)", __func__,
13009 hdd_device_modetoString(pAdapter->device_mode),
13010 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013011
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013012 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013013 if (!pHddCtx)
13014 {
13015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13016 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013017 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013018 }
13019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013020 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013021 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013023 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 }
13025
Agarwal Ashish51325b52014-06-16 16:50:49 +053013026 if (vos_max_concurrent_connections_reached()) {
13027 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13028 return -ECONNREFUSED;
13029 }
13030
Jeff Johnson295189b2012-06-20 16:38:30 -070013031#ifdef WLAN_BTAMP_FEATURE
13032 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013033 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013035 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013037 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 }
13039#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013040
13041 //If Device Mode is Station Concurrent Sessions Exit BMps
13042 //P2P Mode will be taken care in Open/close adapter
13043 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013044 (vos_concurrent_open_sessions_running())) {
13045 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13046 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013047 }
13048
13049 /*Try disconnecting if already in connected state*/
13050 status = wlan_hdd_try_disconnect(pAdapter);
13051 if ( 0 > status)
13052 {
13053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13054 " connection"));
13055 return -EALREADY;
13056 }
13057
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013059 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013060
13061 if ( 0 > status)
13062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 __func__);
13065 return status;
13066 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013067 if ( req->channel )
13068 {
13069 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13070 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013071 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070013072 req->channel->hw_value);
13073 }
13074 else
13075 {
13076 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013077 req->ssid_len, req->bssid,
13078 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013079 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013080
Sushant Kaushikd7083982015-03-18 14:33:24 +053013081 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 {
13083 //ReEnable BMPS if disabled
13084 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13085 (NULL != pHddCtx))
13086 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013087 if (pHddCtx->hdd_wlan_suspended)
13088 {
13089 hdd_set_pwrparams(pHddCtx);
13090 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 //ReEnable Bmps and Imps back
13092 hdd_enable_bmps_imps(pHddCtx);
13093 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013094 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 return status;
13096 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013097 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 EXIT();
13099 return status;
13100}
13101
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013102static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13103 struct net_device *ndev,
13104 struct cfg80211_connect_params *req)
13105{
13106 int ret;
13107 vos_ssr_protect(__func__);
13108 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13109 vos_ssr_unprotect(__func__);
13110
13111 return ret;
13112}
Jeff Johnson295189b2012-06-20 16:38:30 -070013113
13114/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013115 * FUNCTION: wlan_hdd_disconnect
13116 * This function is used to issue a disconnect request to SME
13117 */
13118int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13119{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013120 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013121 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013122 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013123 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013125 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013127 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013128 if (0 != status)
13129 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013130 return status;
13131 }
13132
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013133 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13134 {
13135 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13136 pAdapter->sessionId);
13137 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013138 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013139
Agarwal Ashish47d18112014-08-04 19:55:07 +053013140 /* Need to apply spin lock before decreasing active sessions
13141 * as there can be chance for double decrement if context switch
13142 * Calls hdd_DisConnectHandler.
13143 */
13144
13145 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013146 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13147 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013148 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13149 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013150 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13151 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013152
Abhishek Singhf4669da2014-05-26 15:07:49 +053013153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013154 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13155
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013156 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013157
Mihir Shete182a0b22014-08-18 16:08:48 +053013158 /*
13159 * stop tx queues before deleting STA/BSS context from the firmware.
13160 * tx has to be disabled because the firmware can get busy dropping
13161 * the tx frames after BSS/STA has been deleted and will not send
13162 * back a response resulting in WDI timeout
13163 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013165 netif_tx_disable(pAdapter->dev);
13166 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013167
Mihir Shete182a0b22014-08-18 16:08:48 +053013168 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013169 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13170 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013171 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13172 {
13173 hddLog(VOS_TRACE_LEVEL_INFO,
13174 FL("status = %d, already disconnected"),
13175 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013176
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013177 }
13178 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013179 {
13180 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013181 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013182 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013183 result = -EINVAL;
13184 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013185 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013186 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013187 &pAdapter->disconnect_comp_var,
13188 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013189 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013190 {
13191 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013192 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013193 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013194 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013195 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013196 {
13197 hddLog(VOS_TRACE_LEVEL_ERROR,
13198 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013199 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013200 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013201disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13203 FL("Set HDD connState to eConnectionState_NotConnected"));
13204 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013206 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013207 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013208}
13209
13210
13211/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013212 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 * This function is used to issue a disconnect request to SME
13214 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013215static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 struct net_device *dev,
13217 u16 reason
13218 )
13219{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013221 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013222 tCsrRoamProfile *pRoamProfile;
13223 hdd_station_ctx_t *pHddStaCtx;
13224 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013225#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013226 tANI_U8 staIdx;
13227#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013228
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013230
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013231 if (!pAdapter) {
13232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13233 return -EINVAL;
13234 }
13235
13236 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13237 if (!pHddStaCtx) {
13238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13239 return -EINVAL;
13240 }
13241
13242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13243 status = wlan_hdd_validate_context(pHddCtx);
13244 if (0 != status)
13245 {
13246 return status;
13247 }
13248
13249 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13250
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013251 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13252 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13253 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13255 __func__, hdd_device_modetoString(pAdapter->device_mode),
13256 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013257
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13259 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013260
Jeff Johnson295189b2012-06-20 16:38:30 -070013261 if (NULL != pRoamProfile)
13262 {
13263 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013264 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13265 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013267 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013269 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 switch(reason)
13271 {
13272 case WLAN_REASON_MIC_FAILURE:
13273 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13274 break;
13275
13276 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13277 case WLAN_REASON_DISASSOC_AP_BUSY:
13278 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13279 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13280 break;
13281
13282 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13283 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013284 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013285 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13286 break;
13287
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 default:
13289 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13290 break;
13291 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013292 pScanInfo = &pHddCtx->scan_info;
13293 if (pScanInfo->mScanPending)
13294 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013295 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013296 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013297 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013298 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013299 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013300 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013301#ifdef FEATURE_WLAN_TDLS
13302 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013303 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013304 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013305 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13306 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013307 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013308 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013309 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013311 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013312 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013313 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013314 status = sme_DeleteTdlsPeerSta(
13315 WLAN_HDD_GET_HAL_CTX(pAdapter),
13316 pAdapter->sessionId,
13317 mac);
13318 if (status != eHAL_STATUS_SUCCESS) {
13319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13320 return -EPERM;
13321 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013322 }
13323 }
13324#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013325 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013326 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13327 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013328 {
13329 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013330 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013331 __func__, (int)status );
13332 return -EINVAL;
13333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013335 else
13336 {
13337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13338 "called while in %d state", __func__,
13339 pHddStaCtx->conn_info.connState);
13340 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013341 }
13342 else
13343 {
13344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13345 }
13346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013347 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 return status;
13349}
13350
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013351static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13352 struct net_device *dev,
13353 u16 reason
13354 )
13355{
13356 int ret;
13357 vos_ssr_protect(__func__);
13358 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13359 vos_ssr_unprotect(__func__);
13360
13361 return ret;
13362}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013363
Jeff Johnson295189b2012-06-20 16:38:30 -070013364/*
13365 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013366 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 * settings in IBSS mode.
13368 */
13369static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013370 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 struct cfg80211_ibss_params *params
13372 )
13373{
13374 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013375 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13377 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013378
Jeff Johnson295189b2012-06-20 16:38:30 -070013379 ENTER();
13380
13381 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013382 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013383
13384 if (params->ie_len && ( NULL != params->ie) )
13385 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013386 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13387 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 {
13389 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13390 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13391 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013392 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013394 tDot11fIEWPA dot11WPAIE;
13395 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013396 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013397
Wilson Yang00256342013-10-10 23:13:38 -070013398 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013399 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13400 params->ie_len, DOT11F_EID_WPA);
13401 if ( NULL != ie )
13402 {
13403 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13404 // Unpack the WPA IE
13405 //Skip past the EID byte and length byte - and four byte WiFi OUI
13406 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13407 &ie[2+4],
13408 ie[1] - 4,
13409 &dot11WPAIE);
13410 /*Extract the multicast cipher, the encType for unicast
13411 cipher for wpa-none is none*/
13412 encryptionType =
13413 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13414 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013416
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13418
13419 if (0 > status)
13420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013422 __func__);
13423 return status;
13424 }
13425 }
13426
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013427 pWextState->roamProfile.AuthType.authType[0] =
13428 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13430
13431 if (params->privacy)
13432 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013433 /* Security enabled IBSS, At this time there is no information available
13434 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013436 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 *enable privacy bit in beacons */
13440
13441 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13442 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013443 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13444 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13446 pWextState->roamProfile.EncryptionType.numEntries = 1;
13447 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 return status;
13449}
13450
13451/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013452 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013453 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013454 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013455static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 struct net_device *dev,
13457 struct cfg80211_ibss_params *params
13458 )
13459{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013460 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13462 tCsrRoamProfile *pRoamProfile;
13463 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013464 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13465 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013466 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013467
13468 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013469
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13471 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13472 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013473 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013474 "%s: device_mode = %s (%d)", __func__,
13475 hdd_device_modetoString(pAdapter->device_mode),
13476 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013477
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013478 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013479 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013481 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 }
13483
13484 if (NULL == pWextState)
13485 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013486 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 __func__);
13488 return -EIO;
13489 }
13490
Agarwal Ashish51325b52014-06-16 16:50:49 +053013491 if (vos_max_concurrent_connections_reached()) {
13492 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13493 return -ECONNREFUSED;
13494 }
13495
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013496 /*Try disconnecting if already in connected state*/
13497 status = wlan_hdd_try_disconnect(pAdapter);
13498 if ( 0 > status)
13499 {
13500 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13501 " IBSS connection"));
13502 return -EALREADY;
13503 }
13504
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 pRoamProfile = &pWextState->roamProfile;
13506
13507 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013510 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013511 return -EINVAL;
13512 }
13513
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013514 /* BSSID is provided by upper layers hence no need to AUTO generate */
13515 if (NULL != params->bssid) {
13516 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13517 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13518 hddLog (VOS_TRACE_LEVEL_ERROR,
13519 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13520 return -EIO;
13521 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013522 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013523 }
krunal sonie9002db2013-11-25 14:24:17 -080013524 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13525 {
13526 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13527 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13528 {
13529 hddLog (VOS_TRACE_LEVEL_ERROR,
13530 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13531 return -EIO;
13532 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013533
13534 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013535 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013536 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013537 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013538
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013540 if (NULL !=
13541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13542 params->chandef.chan)
13543#else
13544 params->channel)
13545#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 {
13547 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013548 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13549 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13550 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13551 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013552
13553 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013554 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013555 ieee80211_frequency_to_channel(
13556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13557 params->chandef.chan->center_freq);
13558#else
13559 params->channel->center_freq);
13560#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013561
13562 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13563 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13566 __func__);
13567 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013569
13570 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013572 if (channelNum == validChan[indx])
13573 {
13574 break;
13575 }
13576 }
13577 if (indx >= numChans)
13578 {
13579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 __func__, channelNum);
13581 return -EINVAL;
13582 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013583 /* Set the Operational Channel */
13584 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13585 channelNum);
13586 pRoamProfile->ChannelInfo.numOfChannels = 1;
13587 pHddStaCtx->conn_info.operationChannel = channelNum;
13588 pRoamProfile->ChannelInfo.ChannelList =
13589 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 }
13591
13592 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013593 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 if (status < 0)
13595 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 __func__);
13598 return status;
13599 }
13600
13601 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013603 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013604 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013605
13606 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013609 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013610 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013611}
13612
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013613static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13614 struct net_device *dev,
13615 struct cfg80211_ibss_params *params
13616 )
13617{
13618 int ret = 0;
13619
13620 vos_ssr_protect(__func__);
13621 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13622 vos_ssr_unprotect(__func__);
13623
13624 return ret;
13625}
13626
Jeff Johnson295189b2012-06-20 16:38:30 -070013627/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013628 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013629 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013631static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 struct net_device *dev
13633 )
13634{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013636 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13637 tCsrRoamProfile *pRoamProfile;
13638 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013639 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013640
13641 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013642
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13644 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13645 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013646 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013647 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013648 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013649 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013650 }
13651
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13653 hdd_device_modetoString(pAdapter->device_mode),
13654 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013655 if (NULL == pWextState)
13656 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013657 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 __func__);
13659 return -EIO;
13660 }
13661
13662 pRoamProfile = &pWextState->roamProfile;
13663
13664 /* Issue disconnect only if interface type is set to IBSS */
13665 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13666 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013667 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 __func__);
13669 return -EINVAL;
13670 }
13671
13672 /* Issue Disconnect request */
13673 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13674 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13675 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013677 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 return 0;
13679}
13680
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013681static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13682 struct net_device *dev
13683 )
13684{
13685 int ret = 0;
13686
13687 vos_ssr_protect(__func__);
13688 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13689 vos_ssr_unprotect(__func__);
13690
13691 return ret;
13692}
13693
Jeff Johnson295189b2012-06-20 16:38:30 -070013694/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013695 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 * This function is used to set the phy parameters
13697 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13698 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013699static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 u32 changed)
13701{
13702 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13703 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013704 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013705
13706 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013707
13708 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013709 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13710 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013712 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013713 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013714 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013715 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013716 }
13717
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13719 {
13720 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13721 WNI_CFG_RTS_THRESHOLD_STAMAX :
13722 wiphy->rts_threshold;
13723
13724 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013725 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 hddLog(VOS_TRACE_LEVEL_ERROR,
13728 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 __func__, rts_threshold);
13730 return -EINVAL;
13731 }
13732
13733 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13734 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013735 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737 hddLog(VOS_TRACE_LEVEL_ERROR,
13738 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 __func__, rts_threshold);
13740 return -EIO;
13741 }
13742
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 rts_threshold);
13745 }
13746
13747 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13748 {
13749 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13750 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13751 wiphy->frag_threshold;
13752
13753 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013754 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013756 hddLog(VOS_TRACE_LEVEL_ERROR,
13757 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 frag_threshold);
13759 return -EINVAL;
13760 }
13761
13762 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13763 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013764 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013766 hddLog(VOS_TRACE_LEVEL_ERROR,
13767 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013768 __func__, frag_threshold);
13769 return -EIO;
13770 }
13771
13772 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13773 frag_threshold);
13774 }
13775
13776 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13777 || (changed & WIPHY_PARAM_RETRY_LONG))
13778 {
13779 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13780 wiphy->retry_short :
13781 wiphy->retry_long;
13782
13783 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13784 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 __func__, retry_value);
13788 return -EINVAL;
13789 }
13790
13791 if (changed & WIPHY_PARAM_RETRY_SHORT)
13792 {
13793 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13794 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013795 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013797 hddLog(VOS_TRACE_LEVEL_ERROR,
13798 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 __func__, retry_value);
13800 return -EIO;
13801 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013802 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 __func__, retry_value);
13804 }
13805 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13806 {
13807 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13808 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013809 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013811 hddLog(VOS_TRACE_LEVEL_ERROR,
13812 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013813 __func__, retry_value);
13814 return -EIO;
13815 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013816 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 __func__, retry_value);
13818 }
13819 }
13820
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013821 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 return 0;
13823}
13824
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013825static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13826 u32 changed)
13827{
13828 int ret;
13829
13830 vos_ssr_protect(__func__);
13831 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13832 vos_ssr_unprotect(__func__);
13833
13834 return ret;
13835}
13836
Jeff Johnson295189b2012-06-20 16:38:30 -070013837/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013838 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 * This function is used to set the txpower
13840 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013841static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013842#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13843 struct wireless_dev *wdev,
13844#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013845#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013847#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013849#endif
13850 int dbm)
13851{
13852 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013853 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13855 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013856 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013857
13858 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13861 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13862 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013863 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013864 if (0 != status)
13865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013866 return status;
13867 }
13868
13869 hHal = pHddCtx->hHal;
13870
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13872 dbm, ccmCfgSetCallback,
13873 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013876 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13877 return -EIO;
13878 }
13879
13880 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13881 dbm);
13882
13883 switch(type)
13884 {
13885 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13886 /* Fall through */
13887 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13888 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13891 __func__);
13892 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 }
13894 break;
13895 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 __func__);
13898 return -EOPNOTSUPP;
13899 break;
13900 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13902 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 return -EIO;
13904 }
13905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013906 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 return 0;
13908}
13909
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013910static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13911#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13912 struct wireless_dev *wdev,
13913#endif
13914#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13915 enum tx_power_setting type,
13916#else
13917 enum nl80211_tx_power_setting type,
13918#endif
13919 int dbm)
13920{
13921 int ret;
13922 vos_ssr_protect(__func__);
13923 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13924#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13925 wdev,
13926#endif
13927#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13928 type,
13929#else
13930 type,
13931#endif
13932 dbm);
13933 vos_ssr_unprotect(__func__);
13934
13935 return ret;
13936}
13937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013939 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 * This function is used to read the txpower
13941 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013942static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013943#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13944 struct wireless_dev *wdev,
13945#endif
13946 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013947{
13948
13949 hdd_adapter_t *pAdapter;
13950 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013951 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013952
Jeff Johnsone7245742012-09-05 17:12:55 -070013953 ENTER();
13954
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013955 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013956 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013957 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013958 *dbm = 0;
13959 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013960 }
13961
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13963 if (NULL == pAdapter)
13964 {
13965 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13966 return -ENOENT;
13967 }
13968
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13970 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13971 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 wlan_hdd_get_classAstats(pAdapter);
13973 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13974
Jeff Johnsone7245742012-09-05 17:12:55 -070013975 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 return 0;
13977}
13978
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013979static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13980#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13981 struct wireless_dev *wdev,
13982#endif
13983 int *dbm)
13984{
13985 int ret;
13986
13987 vos_ssr_protect(__func__);
13988 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13989#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13990 wdev,
13991#endif
13992 dbm);
13993 vos_ssr_unprotect(__func__);
13994
13995 return ret;
13996}
13997
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013998static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14000 const u8* mac,
14001#else
14002 u8* mac,
14003#endif
14004 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070014005{
14006 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14007 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14008 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053014009 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014010
14011 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
14012 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070014013
14014 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
14015 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
14016 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
14017 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
14018 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
14019 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
14020 tANI_U16 maxRate = 0;
14021 tANI_U16 myRate;
14022 tANI_U16 currentRate = 0;
14023 tANI_U8 maxSpeedMCS = 0;
14024 tANI_U8 maxMCSIdx = 0;
14025 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014026 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014027 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014028 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014029
Leo Chang6f8870f2013-03-26 18:11:36 -070014030#ifdef WLAN_FEATURE_11AC
14031 tANI_U32 vht_mcs_map;
14032 eDataRate11ACMaxMcs vhtMaxMcs;
14033#endif /* WLAN_FEATURE_11AC */
14034
Jeff Johnsone7245742012-09-05 17:12:55 -070014035 ENTER();
14036
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14038 (0 == ssidlen))
14039 {
14040 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14041 " Invalid ssidlen, %d", __func__, ssidlen);
14042 /*To keep GUI happy*/
14043 return 0;
14044 }
14045
Mukul Sharma811205f2014-07-09 21:07:30 +053014046 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14047 {
14048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14049 "%s: Roaming in progress, so unable to proceed this request", __func__);
14050 return 0;
14051 }
14052
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014053 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014054 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014056 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014057 }
14058
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014059 wlan_hdd_get_station_stats(pAdapter);
14060 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014061
Kiet Lam3b17fc82013-09-27 05:24:08 +053014062 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14063 sinfo->filled |= STATION_INFO_SIGNAL;
14064
c_hpothu09f19542014-05-30 21:53:31 +053014065 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014066 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14067 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014068 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014069 {
14070 rate_flags = pAdapter->maxRateFlags;
14071 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014072
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 //convert to the UI units of 100kbps
14074 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14075
14076#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014077 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 -070014078 sinfo->signal,
14079 pCfg->reportMaxLinkSpeed,
14080 myRate,
14081 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014082 (int) pCfg->linkSpeedRssiMid,
14083 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014084 (int) rate_flags,
14085 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014086#endif //LINKSPEED_DEBUG_ENABLED
14087
14088 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14089 {
14090 // we do not want to necessarily report the current speed
14091 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14092 {
14093 // report the max possible speed
14094 rssidx = 0;
14095 }
14096 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14097 {
14098 // report the max possible speed with RSSI scaling
14099 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14100 {
14101 // report the max possible speed
14102 rssidx = 0;
14103 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014104 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 {
14106 // report middle speed
14107 rssidx = 1;
14108 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014109 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14110 {
14111 // report middle speed
14112 rssidx = 2;
14113 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 else
14115 {
14116 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014117 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 }
14119 }
14120 else
14121 {
14122 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14123 hddLog(VOS_TRACE_LEVEL_ERROR,
14124 "%s: Invalid value for reportMaxLinkSpeed: %u",
14125 __func__, pCfg->reportMaxLinkSpeed);
14126 rssidx = 0;
14127 }
14128
14129 maxRate = 0;
14130
14131 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014132 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14133 OperationalRates, &ORLeng))
14134 {
14135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14136 /*To keep GUI happy*/
14137 return 0;
14138 }
14139
Jeff Johnson295189b2012-06-20 16:38:30 -070014140 for (i = 0; i < ORLeng; i++)
14141 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014142 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014143 {
14144 /* Validate Rate Set */
14145 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14146 {
14147 currentRate = supported_data_rate[j].supported_rate[rssidx];
14148 break;
14149 }
14150 }
14151 /* Update MAX rate */
14152 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14153 }
14154
14155 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014156 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14157 ExtendedRates, &ERLeng))
14158 {
14159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14160 /*To keep GUI happy*/
14161 return 0;
14162 }
14163
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 for (i = 0; i < ERLeng; i++)
14165 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014166 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 {
14168 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14169 {
14170 currentRate = supported_data_rate[j].supported_rate[rssidx];
14171 break;
14172 }
14173 }
14174 /* Update MAX rate */
14175 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14176 }
c_hpothu79aab322014-07-14 21:11:01 +053014177
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014178 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014179 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014180 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014181 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 {
c_hpothu79aab322014-07-14 21:11:01 +053014183 if (rate_flags & eHAL_TX_RATE_VHT80)
14184 mode = 2;
14185 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14186 mode = 1;
14187 else
14188 mode = 0;
14189
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014190 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14191 MCSRates, &MCSLeng))
14192 {
14193 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14194 /*To keep GUI happy*/
14195 return 0;
14196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014198#ifdef WLAN_FEATURE_11AC
14199 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014200 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014201 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014202 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014203 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014204 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014205 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014206 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014207 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014208 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014209 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014210 maxMCSIdx = 7;
14211 }
14212 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14213 {
14214 maxMCSIdx = 8;
14215 }
14216 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14217 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014218 //VHT20 is supporting 0~8
14219 if (rate_flags & eHAL_TX_RATE_VHT20)
14220 maxMCSIdx = 8;
14221 else
14222 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014223 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014224
c_hpothu79aab322014-07-14 21:11:01 +053014225 if (0 != rssidx)/*check for scaled */
14226 {
14227 //get middle rate MCS index if rssi=1/2
14228 for (i=0; i <= maxMCSIdx; i++)
14229 {
14230 if (sinfo->signal <= rssiMcsTbl[mode][i])
14231 {
14232 maxMCSIdx = i;
14233 break;
14234 }
14235 }
14236 }
14237
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014238 if (rate_flags & eHAL_TX_RATE_VHT80)
14239 {
14240 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14241 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14242 }
14243 else if (rate_flags & eHAL_TX_RATE_VHT40)
14244 {
14245 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14246 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14247 }
14248 else if (rate_flags & eHAL_TX_RATE_VHT20)
14249 {
14250 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14251 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14252 }
14253
Leo Chang6f8870f2013-03-26 18:11:36 -070014254 maxSpeedMCS = 1;
14255 if (currentRate > maxRate)
14256 {
14257 maxRate = currentRate;
14258 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014259
Leo Chang6f8870f2013-03-26 18:11:36 -070014260 }
14261 else
14262#endif /* WLAN_FEATURE_11AC */
14263 {
14264 if (rate_flags & eHAL_TX_RATE_HT40)
14265 {
14266 rateFlag |= 1;
14267 }
14268 if (rate_flags & eHAL_TX_RATE_SGI)
14269 {
14270 rateFlag |= 2;
14271 }
14272
Girish Gowli01abcee2014-07-31 20:18:55 +053014273 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014274 if (rssidx == 1 || rssidx == 2)
14275 {
14276 //get middle rate MCS index if rssi=1/2
14277 for (i=0; i <= 7; i++)
14278 {
14279 if (sinfo->signal <= rssiMcsTbl[mode][i])
14280 {
14281 temp = i+1;
14282 break;
14283 }
14284 }
14285 }
c_hpothu79aab322014-07-14 21:11:01 +053014286
14287 for (i = 0; i < MCSLeng; i++)
14288 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014289 for (j = 0; j < temp; j++)
14290 {
14291 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14292 {
14293 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014294 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014295 break;
14296 }
14297 }
14298 if ((j < temp) && (currentRate > maxRate))
14299 {
14300 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014302 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014303 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014304 }
14305 }
14306
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014307 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14308 {
14309 maxRate = myRate;
14310 maxSpeedMCS = 1;
14311 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14312 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014314 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 {
14316 maxRate = myRate;
14317 if (rate_flags & eHAL_TX_RATE_LEGACY)
14318 {
14319 maxSpeedMCS = 0;
14320 }
14321 else
14322 {
14323 maxSpeedMCS = 1;
14324 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14325 }
14326 }
14327
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014328 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014329 {
14330 sinfo->txrate.legacy = maxRate;
14331#ifdef LINKSPEED_DEBUG_ENABLED
14332 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14333#endif //LINKSPEED_DEBUG_ENABLED
14334 }
14335 else
14336 {
14337 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014338#ifdef WLAN_FEATURE_11AC
14339 sinfo->txrate.nss = 1;
14340 if (rate_flags & eHAL_TX_RATE_VHT80)
14341 {
14342 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014343 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014344 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014345 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014346 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014347 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14348 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14349 }
14350 else if (rate_flags & eHAL_TX_RATE_VHT20)
14351 {
14352 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14353 }
14354#endif /* WLAN_FEATURE_11AC */
14355 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14356 {
14357 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14358 if (rate_flags & eHAL_TX_RATE_HT40)
14359 {
14360 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14361 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 if (rate_flags & eHAL_TX_RATE_SGI)
14364 {
14365 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14366 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014367
Jeff Johnson295189b2012-06-20 16:38:30 -070014368#ifdef LINKSPEED_DEBUG_ENABLED
14369 pr_info("Reporting MCS rate %d flags %x\n",
14370 sinfo->txrate.mcs,
14371 sinfo->txrate.flags );
14372#endif //LINKSPEED_DEBUG_ENABLED
14373 }
14374 }
14375 else
14376 {
14377 // report current rate instead of max rate
14378
14379 if (rate_flags & eHAL_TX_RATE_LEGACY)
14380 {
14381 //provide to the UI in units of 100kbps
14382 sinfo->txrate.legacy = myRate;
14383#ifdef LINKSPEED_DEBUG_ENABLED
14384 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14385#endif //LINKSPEED_DEBUG_ENABLED
14386 }
14387 else
14388 {
14389 //must be MCS
14390 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014391#ifdef WLAN_FEATURE_11AC
14392 sinfo->txrate.nss = 1;
14393 if (rate_flags & eHAL_TX_RATE_VHT80)
14394 {
14395 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14396 }
14397 else
14398#endif /* WLAN_FEATURE_11AC */
14399 {
14400 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14401 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014402 if (rate_flags & eHAL_TX_RATE_SGI)
14403 {
14404 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14405 }
14406 if (rate_flags & eHAL_TX_RATE_HT40)
14407 {
14408 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14409 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014410#ifdef WLAN_FEATURE_11AC
14411 else if (rate_flags & eHAL_TX_RATE_VHT80)
14412 {
14413 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14414 }
14415#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014416#ifdef LINKSPEED_DEBUG_ENABLED
14417 pr_info("Reporting actual MCS rate %d flags %x\n",
14418 sinfo->txrate.mcs,
14419 sinfo->txrate.flags );
14420#endif //LINKSPEED_DEBUG_ENABLED
14421 }
14422 }
14423 sinfo->filled |= STATION_INFO_TX_BITRATE;
14424
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014425 sinfo->tx_packets =
14426 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14427 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14428 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14429 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14430
14431 sinfo->tx_retries =
14432 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14433 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14434 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14435 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14436
14437 sinfo->tx_failed =
14438 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14439 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14440 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14441 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14442
14443 sinfo->filled |=
14444 STATION_INFO_TX_PACKETS |
14445 STATION_INFO_TX_RETRIES |
14446 STATION_INFO_TX_FAILED;
14447
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014448 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14449 TRACE_CODE_HDD_CFG80211_GET_STA,
14450 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014451 EXIT();
14452 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014453}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014454#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14455static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14456 const u8* mac, struct station_info *sinfo)
14457#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014458static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14459 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014460#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014461{
14462 int ret;
14463
14464 vos_ssr_protect(__func__);
14465 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14466 vos_ssr_unprotect(__func__);
14467
14468 return ret;
14469}
14470
14471static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014472 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014473{
14474 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014475 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014477 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014478
Jeff Johnsone7245742012-09-05 17:12:55 -070014479 ENTER();
14480
Jeff Johnson295189b2012-06-20 16:38:30 -070014481 if (NULL == pAdapter)
14482 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014484 return -ENODEV;
14485 }
14486
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14488 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14489 pAdapter->sessionId, timeout));
14490
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014491 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014492 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014493 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014494 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014495 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014496 }
14497
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014498 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14499 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14500 (pHddCtx->cfg_ini->fhostArpOffload) &&
14501 (eConnectionState_Associated ==
14502 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14503 {
Amar Singhald53568e2013-09-26 11:03:45 -070014504
14505 hddLog(VOS_TRACE_LEVEL_INFO,
14506 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014507 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014508 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14509 {
14510 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014511 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014512 __func__, vos_status);
14513 }
14514 }
14515
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 /**The get power cmd from the supplicant gets updated by the nl only
14517 *on successful execution of the function call
14518 *we are oppositely mapped w.r.t mode in the driver
14519 **/
14520 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14521
14522 if (VOS_STATUS_E_FAILURE == vos_status)
14523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14525 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 return -EINVAL;
14527 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014528 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014529 return 0;
14530}
14531
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014532static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14533 struct net_device *dev, bool mode, int timeout)
14534{
14535 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014536
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014537 vos_ssr_protect(__func__);
14538 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14539 vos_ssr_unprotect(__func__);
14540
14541 return ret;
14542}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014543static const struct
14544nla_policy
14545qca_wlan_vendor_get_wifi_info_policy[
14546 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
14547 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
14548 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
14549};
14550
14551/**
14552 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
14553 * @wiphy: pointer to wireless wiphy structure.
14554 * @wdev: pointer to wireless_dev structure.
14555 * @data: Pointer to the data to be passed via vendor interface
14556 * @data_len:Length of the data to be passed
14557 *
14558 * This is called when wlan driver needs to send wifi driver related info
14559 * (driver/fw version) to the user space application upon request.
14560 *
14561 * Return: Return the Success or Failure code.
14562 */
14563static int
14564wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
14565 struct wireless_dev *wdev,
14566 const void *data, int data_len)
14567{
14568 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
14569 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
14570 tSirVersionString version;
14571 uint32 version_len;
14572 uint8 attr;
14573 int status;
14574 struct sk_buff *reply_skb = NULL;
14575
14576 if (VOS_FTM_MODE == hdd_get_conparam()) {
14577 hddLog(LOGE, FL("Command not allowed in FTM mode"));
14578 return -EINVAL;
14579 }
14580
14581 status = wlan_hdd_validate_context(hdd_ctx);
14582 if (0 != status) {
14583 hddLog(LOGE, FL("HDD context is not valid"));
14584 return -EINVAL;
14585 }
14586
14587 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
14588 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
14589 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
14590 return -EINVAL;
14591 }
14592
14593 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
14594 hddLog(LOG1, FL("Rcvd req for Driver version "
14595 "Driver version is %s"),QWLAN_VERSIONSTR);
14596 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
14597 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
14598 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
14599 hddLog(LOG1, FL("Rcvd req for FW version "
14600 "FW version is %s"), hdd_ctx->fw_Version);
14601 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
14602 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
14603 } else {
14604 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
14605 return -EINVAL;
14606 }
14607
14608 version_len = strlen(version);
14609 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
14610 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
14611 if (!reply_skb) {
14612 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
14613 return -ENOMEM;
14614 }
14615
14616 if (nla_put(reply_skb, attr, version_len, version)) {
14617 hddLog(LOGE, FL("nla put fail"));
14618 kfree_skb(reply_skb);
14619 return -EINVAL;
14620 }
14621
14622 return cfg80211_vendor_cmd_reply(reply_skb);
14623}
14624
Jeff Johnson295189b2012-06-20 16:38:30 -070014625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014626static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14627 struct net_device *netdev,
14628 u8 key_index)
14629{
14630 ENTER();
14631 return 0;
14632}
14633
Jeff Johnson295189b2012-06-20 16:38:30 -070014634static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014635 struct net_device *netdev,
14636 u8 key_index)
14637{
14638 int ret;
14639 vos_ssr_protect(__func__);
14640 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14641 vos_ssr_unprotect(__func__);
14642 return ret;
14643}
14644#endif //LINUX_VERSION_CODE
14645
14646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14647static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14648 struct net_device *dev,
14649 struct ieee80211_txq_params *params)
14650{
14651 ENTER();
14652 return 0;
14653}
14654#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14655static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14656 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014657{
Jeff Johnsone7245742012-09-05 17:12:55 -070014658 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 return 0;
14660}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014661#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014662
14663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14664static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014665 struct net_device *dev,
14666 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014667{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014668 int ret;
14669
14670 vos_ssr_protect(__func__);
14671 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14672 vos_ssr_unprotect(__func__);
14673 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014674}
14675#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14676static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14677 struct ieee80211_txq_params *params)
14678{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014679 int ret;
14680
14681 vos_ssr_protect(__func__);
14682 ret = __wlan_hdd_set_txq_params(wiphy, params);
14683 vos_ssr_unprotect(__func__);
14684 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014685}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014686#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014687
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014688static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014689 struct net_device *dev,
14690 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014691{
14692 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014693 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014694 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014695 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014696 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014697 v_CONTEXT_t pVosContext = NULL;
14698 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014699
Jeff Johnsone7245742012-09-05 17:12:55 -070014700 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014701
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014702 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 return -EINVAL;
14706 }
14707
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014708 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14709 TRACE_CODE_HDD_CFG80211_DEL_STA,
14710 pAdapter->sessionId, pAdapter->device_mode));
14711
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014712 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14713 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014714 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014715 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014716 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014717 }
14718
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014721 )
14722 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014723 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14724 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14725 if(pSapCtx == NULL){
14726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14727 FL("psapCtx is NULL"));
14728 return -ENOENT;
14729 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014730 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014731 {
14732 v_U16_t i;
14733 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14734 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014735 if ((pSapCtx->aStaInfo[i].isUsed) &&
14736 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014737 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014738 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014739 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014740 ETHER_ADDR_LEN);
14741
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014743 "%s: Delete STA with MAC::"
14744 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014745 __func__,
14746 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14747 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014748 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014749 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014750 }
14751 }
14752 }
14753 else
14754 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014755
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014756 vos_status = hdd_softap_GetStaId(pAdapter,
14757 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014758 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14759 {
14760 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014761 "%s: Skip this DEL STA as this is not used::"
14762 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014763 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014764 return -ENOENT;
14765 }
14766
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014767 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014768 {
14769 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014770 "%s: Skip this DEL STA as deauth is in progress::"
14771 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014772 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014773 return -ENOENT;
14774 }
14775
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014776 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014777
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 hddLog(VOS_TRACE_LEVEL_INFO,
14779 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014780 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014781 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014782 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014783
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014784 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014785 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14786 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014787 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014788 hddLog(VOS_TRACE_LEVEL_INFO,
14789 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014790 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014791 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014792 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014793 return -ENOENT;
14794 }
14795
Jeff Johnson295189b2012-06-20 16:38:30 -070014796 }
14797 }
14798
14799 EXIT();
14800
14801 return 0;
14802}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014803
14804#ifdef CFG80211_DEL_STA_V2
14805static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14806 struct net_device *dev,
14807 struct station_del_parameters *param)
14808#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14810static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14811 struct net_device *dev, const u8 *mac)
14812#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014813static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14814 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014815#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014816#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014817{
14818 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014819 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014820
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014821 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014822
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014823#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014824 if (NULL == param) {
14825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014826 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014827 return -EINVAL;
14828 }
14829
14830 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14831 param->subtype, &delStaParams);
14832
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014833#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014834 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014835 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014836#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014837 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14838
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014839 vos_ssr_unprotect(__func__);
14840
14841 return ret;
14842}
14843
14844static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014845 struct net_device *dev,
14846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14847 const u8 *mac,
14848#else
14849 u8 *mac,
14850#endif
14851 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014852{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014853 hdd_adapter_t *pAdapter;
14854 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014855 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014856#ifdef FEATURE_WLAN_TDLS
14857 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014858
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014859 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014860
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014861 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14862 if (NULL == pAdapter)
14863 {
14864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14865 "%s: Adapter is NULL",__func__);
14866 return -EINVAL;
14867 }
14868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14869 status = wlan_hdd_validate_context(pHddCtx);
14870 if (0 != status)
14871 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014872 return status;
14873 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014874
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014875 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14876 TRACE_CODE_HDD_CFG80211_ADD_STA,
14877 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014878 mask = params->sta_flags_mask;
14879
14880 set = params->sta_flags_set;
14881
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014883 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14884 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014885
14886 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14887 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014888 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014889 }
14890 }
14891#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014892 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014893 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014894}
14895
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14897static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14898 struct net_device *dev, const u8 *mac,
14899 struct station_parameters *params)
14900#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014901static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14902 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014903#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014904{
14905 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014906
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014907 vos_ssr_protect(__func__);
14908 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14909 vos_ssr_unprotect(__func__);
14910
14911 return ret;
14912}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014913#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014914
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014915static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014916 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014917{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14919 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014920 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014921 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014922 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014923 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014924
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014925 ENTER();
14926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014927 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014928 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014929 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014931 return -EINVAL;
14932 }
14933
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014934 if (!pmksa) {
14935 hddLog(LOGE, FL("pmksa is NULL"));
14936 return -EINVAL;
14937 }
14938
14939 if (!pmksa->bssid || !pmksa->pmkid) {
14940 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14941 pmksa->bssid, pmksa->pmkid);
14942 return -EINVAL;
14943 }
14944
14945 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14946 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14947
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14949 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014950 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014952 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014953 }
14954
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014955 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014956 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14957
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014958 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14959 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014960
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014961 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014962 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014963 &pmk_id, 1, FALSE);
14964
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014965 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14966 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14967 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014969 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014970 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014971}
14972
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014973static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14974 struct cfg80211_pmksa *pmksa)
14975{
14976 int ret;
14977
14978 vos_ssr_protect(__func__);
14979 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14980 vos_ssr_unprotect(__func__);
14981
14982 return ret;
14983}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014984
Wilson Yang6507c4e2013-10-01 20:11:19 -070014985
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014986static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014987 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014988{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014989 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14990 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014991 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014992 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014993
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014994 ENTER();
14995
Wilson Yang6507c4e2013-10-01 20:11:19 -070014996 /* Validate pAdapter */
14997 if (NULL == pAdapter)
14998 {
14999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
15000 return -EINVAL;
15001 }
15002
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015003 if (!pmksa) {
15004 hddLog(LOGE, FL("pmksa is NULL"));
15005 return -EINVAL;
15006 }
15007
15008 if (!pmksa->bssid) {
15009 hddLog(LOGE, FL("pmksa->bssid is NULL"));
15010 return -EINVAL;
15011 }
15012
Kiet Lam98c46a12014-10-31 15:34:57 -070015013 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
15014 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15015
Wilson Yang6507c4e2013-10-01 20:11:19 -070015016 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15017 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015018 if (0 != status)
15019 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015020 return status;
15021 }
15022
15023 /*Retrieve halHandle*/
15024 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15025
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15027 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
15028 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015029 /* Delete the PMKID CSR cache */
15030 if (eHAL_STATUS_SUCCESS !=
15031 sme_RoamDelPMKIDfromCache(halHandle,
15032 pAdapter->sessionId, pmksa->bssid, FALSE)) {
15033 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
15034 MAC_ADDR_ARRAY(pmksa->bssid));
15035 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015036 }
15037
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015038 EXIT();
15039 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015040}
15041
Wilson Yang6507c4e2013-10-01 20:11:19 -070015042
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015043static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
15044 struct cfg80211_pmksa *pmksa)
15045{
15046 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015047
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015048 vos_ssr_protect(__func__);
15049 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
15050 vos_ssr_unprotect(__func__);
15051
15052 return ret;
15053
15054}
15055
15056static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015057{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015058 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15059 tHalHandle halHandle;
15060 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015061 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015062
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015063 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070015064
15065 /* Validate pAdapter */
15066 if (NULL == pAdapter)
15067 {
15068 hddLog(VOS_TRACE_LEVEL_ERROR,
15069 "%s: Invalid Adapter" ,__func__);
15070 return -EINVAL;
15071 }
15072
15073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15074 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015075 if (0 != status)
15076 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015077 return status;
15078 }
15079
15080 /*Retrieve halHandle*/
15081 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15082
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015083 /* Flush the PMKID cache in CSR */
15084 if (eHAL_STATUS_SUCCESS !=
15085 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
15086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
15087 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015088 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015089 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080015090 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015091}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015092
15093static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
15094{
15095 int ret;
15096
15097 vos_ssr_protect(__func__);
15098 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
15099 vos_ssr_unprotect(__func__);
15100
15101 return ret;
15102}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015103#endif
15104
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015105#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015106static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15107 struct net_device *dev,
15108 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015109{
15110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15111 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015112 hdd_context_t *pHddCtx;
15113 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015114
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015115 ENTER();
15116
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015117 if (NULL == pAdapter)
15118 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015120 return -ENODEV;
15121 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015122 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15123 ret = wlan_hdd_validate_context(pHddCtx);
15124 if (0 != ret)
15125 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015126 return ret;
15127 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015128 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015129 if (NULL == pHddStaCtx)
15130 {
15131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15132 return -EINVAL;
15133 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15136 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15137 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015138 // Added for debug on reception of Re-assoc Req.
15139 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15140 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015141 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015142 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015143 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015144 }
15145
15146#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015147 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015148 ftie->ie_len);
15149#endif
15150
15151 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015152 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15153 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015154 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015155
15156 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015157 return 0;
15158}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015159
15160static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15161 struct net_device *dev,
15162 struct cfg80211_update_ft_ies_params *ftie)
15163{
15164 int ret;
15165
15166 vos_ssr_protect(__func__);
15167 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15168 vos_ssr_unprotect(__func__);
15169
15170 return ret;
15171}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015172#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015173
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015174#ifdef FEATURE_WLAN_SCAN_PNO
15175
15176void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15177 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15178{
15179 int ret;
15180 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15181 hdd_context_t *pHddCtx;
15182
Nirav Shah80830bf2013-12-31 16:35:12 +053015183 ENTER();
15184
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015185 if (NULL == pAdapter)
15186 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015188 "%s: HDD adapter is Null", __func__);
15189 return ;
15190 }
15191
15192 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15193 if (NULL == pHddCtx)
15194 {
15195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15196 "%s: HDD context is Null!!!", __func__);
15197 return ;
15198 }
15199
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015200 spin_lock(&pHddCtx->schedScan_lock);
15201 if (TRUE == pHddCtx->isWiphySuspended)
15202 {
15203 pHddCtx->isSchedScanUpdatePending = TRUE;
15204 spin_unlock(&pHddCtx->schedScan_lock);
15205 hddLog(VOS_TRACE_LEVEL_INFO,
15206 "%s: Update cfg80211 scan database after it resume", __func__);
15207 return ;
15208 }
15209 spin_unlock(&pHddCtx->schedScan_lock);
15210
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015211 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15212
15213 if (0 > ret)
15214 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15215
15216 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15218 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015219}
15220
15221/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015222 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015223 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015224 */
15225static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15226{
15227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15228 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015229 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15231 int status = 0;
15232 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15233
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015234 /* The current firmware design does not allow PNO during any
15235 * active sessions. Hence, determine the active sessions
15236 * and return a failure.
15237 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015238 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15239 {
15240 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015241 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015242
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015243 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15244 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15245 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15246 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15247 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015248 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015249 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015250 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015251 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015252 }
15253 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15254 pAdapterNode = pNext;
15255 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015256 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015257}
15258
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015259void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15260{
15261 hdd_adapter_t *pAdapter = callbackContext;
15262 hdd_context_t *pHddCtx;
15263
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015264 ENTER();
15265
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015266 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15267 {
15268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15269 FL("Invalid adapter or adapter has invalid magic"));
15270 return;
15271 }
15272
15273 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15274 if (0 != wlan_hdd_validate_context(pHddCtx))
15275 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015276 return;
15277 }
15278
c_hpothub53c45d2014-08-18 16:53:14 +053015279 if (VOS_STATUS_SUCCESS != status)
15280 {
15281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015282 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015283 pHddCtx->isPnoEnable = FALSE;
15284 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015285
15286 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15287 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015288 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015289}
15290
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015291/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015292 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15293 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015294 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015295static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015296 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15297{
15298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015299 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015300 hdd_context_t *pHddCtx;
15301 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015302 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015303 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15304 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015305 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15306 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015307 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015308 hdd_config_t *pConfig = NULL;
15309 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015311 ENTER();
15312
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015313 if (NULL == pAdapter)
15314 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015316 "%s: HDD adapter is Null", __func__);
15317 return -ENODEV;
15318 }
15319
15320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015321 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015322
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015323 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015324 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015325 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015326 }
15327
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015328 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015329 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15330 if (NULL == hHal)
15331 {
15332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15333 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015334 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015335 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15337 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15338 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015339 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015340 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015341 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015342 {
15343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15344 "%s: aborting the existing scan is unsuccessfull", __func__);
15345 return -EBUSY;
15346 }
15347
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015348 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015349 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015351 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015352 return -EBUSY;
15353 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015354
c_hpothu37f21312014-04-09 21:49:54 +053015355 if (TRUE == pHddCtx->isPnoEnable)
15356 {
15357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15358 FL("already PNO is enabled"));
15359 return -EBUSY;
15360 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015361
15362 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15363 {
15364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15365 "%s: abort ROC failed ", __func__);
15366 return -EBUSY;
15367 }
15368
c_hpothu37f21312014-04-09 21:49:54 +053015369 pHddCtx->isPnoEnable = TRUE;
15370
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015371 pnoRequest.enable = 1; /*Enable PNO */
15372 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015373
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015374 if (( !pnoRequest.ucNetworksCount ) ||
15375 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015376 {
15377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015378 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015379 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015380 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015381 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015382 goto error;
15383 }
15384
15385 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15386 {
15387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015388 "%s: Incorrect number of channels %d",
15389 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015390 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015391 goto error;
15392 }
15393
15394 /* Framework provides one set of channels(all)
15395 * common for all saved profile */
15396 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15397 channels_allowed, &num_channels_allowed))
15398 {
15399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15400 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015401 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015402 goto error;
15403 }
15404 /* Checking each channel against allowed channel list */
15405 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015406 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015407 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015408 char chList [(request->n_channels*5)+1];
15409 int len;
15410 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015411 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015412 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015413 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015414 if (request->channels[i]->hw_value == channels_allowed[indx])
15415 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015416 if ((!pConfig->enableDFSPnoChnlScan) &&
15417 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15418 {
15419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15420 "%s : Dropping DFS channel : %d",
15421 __func__,channels_allowed[indx]);
15422 num_ignore_dfs_ch++;
15423 break;
15424 }
15425
Nirav Shah80830bf2013-12-31 16:35:12 +053015426 valid_ch[num_ch++] = request->channels[i]->hw_value;
15427 len += snprintf(chList+len, 5, "%d ",
15428 request->channels[i]->hw_value);
15429 break ;
15430 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015431 }
15432 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015433 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015434
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015435 /*If all channels are DFS and dropped, then ignore the PNO request*/
15436 if (num_ignore_dfs_ch == request->n_channels)
15437 {
15438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15439 "%s : All requested channels are DFS channels", __func__);
15440 ret = -EINVAL;
15441 goto error;
15442 }
15443 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015444
15445 pnoRequest.aNetworks =
15446 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15447 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015448 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015449 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15450 FL("failed to allocate memory aNetworks %u"),
15451 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15452 goto error;
15453 }
15454 vos_mem_zero(pnoRequest.aNetworks,
15455 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15456
15457 /* Filling per profile params */
15458 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15459 {
15460 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015461 request->match_sets[i].ssid.ssid_len;
15462
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015463 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15464 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015465 {
15466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015467 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015468 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015469 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015470 goto error;
15471 }
15472
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015473 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015474 request->match_sets[i].ssid.ssid,
15475 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15477 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015478 i, pnoRequest.aNetworks[i].ssId.ssId);
15479 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15480 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15481 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015482
15483 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015484 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15485 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015486
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015487 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015488 }
15489
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015490 for (i = 0; i < request->n_ssids; i++)
15491 {
15492 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015493 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015494 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015495 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015496 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015497 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015498 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015499 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015500 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015501 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015502 break;
15503 }
15504 j++;
15505 }
15506 }
15507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15508 "Number of hidden networks being Configured = %d",
15509 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015511 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015512
15513 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15514 if (pnoRequest.p24GProbeTemplate == NULL)
15515 {
15516 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15517 FL("failed to allocate memory p24GProbeTemplate %u"),
15518 SIR_PNO_MAX_PB_REQ_SIZE);
15519 goto error;
15520 }
15521
15522 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15523 if (pnoRequest.p5GProbeTemplate == NULL)
15524 {
15525 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15526 FL("failed to allocate memory p5GProbeTemplate %u"),
15527 SIR_PNO_MAX_PB_REQ_SIZE);
15528 goto error;
15529 }
15530
15531 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15532 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15533
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015534 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15535 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015536 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015537 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15538 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15539 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015540
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015541 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15542 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15543 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015544 }
15545
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015546 /* Driver gets only one time interval which is hardcoded in
15547 * supplicant for 10000ms. Taking power consumption into account 6 timers
15548 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15549 * 80,160,320 secs. And number of scan cycle for each timer
15550 * is configurable through INI param gPNOScanTimerRepeatValue.
15551 * If it is set to 0 only one timer will be used and PNO scan cycle
15552 * will be repeated after each interval specified by supplicant
15553 * till PNO is disabled.
15554 */
15555 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015556 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015557 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015558 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015559 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15560
15561 tempInterval = (request->interval)/1000;
15562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15563 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15564 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015565 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015566 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015567 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015568 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015569 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015570 tempInterval *= 2;
15571 }
15572 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015573 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015574
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015575 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015576
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015577 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015578 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15579 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015580 pAdapter->pno_req_status = 0;
15581
Nirav Shah80830bf2013-12-31 16:35:12 +053015582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15583 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015584 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15585 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015586
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015587 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015588 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015589 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15590 if (eHAL_STATUS_SUCCESS != status)
15591 {
15592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015593 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015594 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015595 goto error;
15596 }
15597
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015598 ret = wait_for_completion_timeout(
15599 &pAdapter->pno_comp_var,
15600 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15601 if (0 >= ret)
15602 {
15603 // Did not receive the response for PNO enable in time.
15604 // Assuming the PNO enable was success.
15605 // Returning error from here, because we timeout, results
15606 // in side effect of Wifi (Wifi Setting) not to work.
15607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15608 FL("Timed out waiting for PNO to be Enabled"));
15609 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015610 }
15611
15612 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015613 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015614
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015615error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15617 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015618 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015619 if (pnoRequest.aNetworks)
15620 vos_mem_free(pnoRequest.aNetworks);
15621 if (pnoRequest.p24GProbeTemplate)
15622 vos_mem_free(pnoRequest.p24GProbeTemplate);
15623 if (pnoRequest.p5GProbeTemplate)
15624 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015625
15626 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015627 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015628}
15629
15630/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015631 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15632 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015633 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015634static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15635 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15636{
15637 int ret;
15638
15639 vos_ssr_protect(__func__);
15640 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15641 vos_ssr_unprotect(__func__);
15642
15643 return ret;
15644}
15645
15646/*
15647 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15648 * Function to disable PNO
15649 */
15650static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015651 struct net_device *dev)
15652{
15653 eHalStatus status = eHAL_STATUS_FAILURE;
15654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15655 hdd_context_t *pHddCtx;
15656 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015657 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015658 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015659
15660 ENTER();
15661
15662 if (NULL == pAdapter)
15663 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015665 "%s: HDD adapter is Null", __func__);
15666 return -ENODEV;
15667 }
15668
15669 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015670
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015671 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015672 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015674 "%s: HDD context is Null", __func__);
15675 return -ENODEV;
15676 }
15677
15678 /* The return 0 is intentional when isLogpInProgress and
15679 * isLoadUnloadInProgress. We did observe a crash due to a return of
15680 * failure in sched_scan_stop , especially for a case where the unload
15681 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15682 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15683 * success. If it returns a failure , then its next invocation due to the
15684 * clean up of the second interface will have the dev pointer corresponding
15685 * to the first one leading to a crash.
15686 */
15687 if (pHddCtx->isLogpInProgress)
15688 {
15689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15690 "%s: LOGP in Progress. Ignore!!!", __func__);
15691 return ret;
15692 }
15693
Mihir Shete18156292014-03-11 15:38:30 +053015694 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015695 {
15696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15697 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15698 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015699 }
15700
15701 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15702 if (NULL == hHal)
15703 {
15704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15705 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015706 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015707 }
15708
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015709 pnoRequest.enable = 0; /* Disable PNO */
15710 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015711
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15713 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15714 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015715 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015716 pAdapter->sessionId,
15717 NULL, pAdapter);
15718 if (eHAL_STATUS_SUCCESS != status)
15719 {
15720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15721 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015722 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015723 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015724 }
c_hpothu37f21312014-04-09 21:49:54 +053015725 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015726
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015727error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015729 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015730
15731 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015732 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015733}
15734
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015735/*
15736 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15737 * NL interface to disable PNO
15738 */
15739static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15740 struct net_device *dev)
15741{
15742 int ret;
15743
15744 vos_ssr_protect(__func__);
15745 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15746 vos_ssr_unprotect(__func__);
15747
15748 return ret;
15749}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015750#endif /*FEATURE_WLAN_SCAN_PNO*/
15751
15752
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015753#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015754#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015755static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15756 struct net_device *dev,
15757 u8 *peer, u8 action_code,
15758 u8 dialog_token,
15759 u16 status_code, u32 peer_capability,
15760 const u8 *buf, size_t len)
15761#else /* TDLS_MGMT_VERSION2 */
15762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15763static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15764 struct net_device *dev,
15765 const u8 *peer, u8 action_code,
15766 u8 dialog_token, u16 status_code,
15767 u32 peer_capability, bool initiator,
15768 const u8 *buf, size_t len)
15769#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15770static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15771 struct net_device *dev,
15772 const u8 *peer, u8 action_code,
15773 u8 dialog_token, u16 status_code,
15774 u32 peer_capability, const u8 *buf,
15775 size_t len)
15776#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15777static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15778 struct net_device *dev,
15779 u8 *peer, u8 action_code,
15780 u8 dialog_token,
15781 u16 status_code, u32 peer_capability,
15782 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015783#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015784static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15785 struct net_device *dev,
15786 u8 *peer, u8 action_code,
15787 u8 dialog_token,
15788 u16 status_code, const u8 *buf,
15789 size_t len)
15790#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015791#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015792{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015793 hdd_adapter_t *pAdapter;
15794 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015795 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015796 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015797 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015798 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015799 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015800#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015801 u32 peer_capability = 0;
15802#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015803 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015804 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015805
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015806 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15807 if (NULL == pAdapter)
15808 {
15809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15810 "%s: Adapter is NULL",__func__);
15811 return -EINVAL;
15812 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015813 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15814 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15815 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015816
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015817 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015818 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015821 "Invalid arguments");
15822 return -EINVAL;
15823 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015824
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015825 if (pHddCtx->isLogpInProgress)
15826 {
15827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15828 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015829 wlan_hdd_tdls_set_link_status(pAdapter,
15830 peer,
15831 eTDLS_LINK_IDLE,
15832 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015833 return -EBUSY;
15834 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015835
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015836 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15837 {
15838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15839 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15840 return -EAGAIN;
15841 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015842
Hoonki Lee27511902013-03-14 18:19:06 -070015843 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015844 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015846 "%s: TDLS mode is disabled OR not enabled in FW."
15847 MAC_ADDRESS_STR " action %d declined.",
15848 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015849 return -ENOTSUPP;
15850 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015851
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015852 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15853
15854 if( NULL == pHddStaCtx )
15855 {
15856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15857 "%s: HDD station context NULL ",__func__);
15858 return -EINVAL;
15859 }
15860
15861 /* STA should be connected and authenticated
15862 * before sending any TDLS frames
15863 */
15864 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15865 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15866 {
15867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15868 "STA is not connected or unauthenticated. "
15869 "connState %u, uIsAuthenticated %u",
15870 pHddStaCtx->conn_info.connState,
15871 pHddStaCtx->conn_info.uIsAuthenticated);
15872 return -EAGAIN;
15873 }
15874
Hoonki Lee27511902013-03-14 18:19:06 -070015875 /* other than teardown frame, other mgmt frames are not sent if disabled */
15876 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15877 {
15878 /* if tdls_mode is disabled to respond to peer's request */
15879 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15880 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015882 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015883 " TDLS mode is disabled. action %d declined.",
15884 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015885
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015886 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015887 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015888
15889 if (vos_max_concurrent_connections_reached())
15890 {
15891 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15892 return -EINVAL;
15893 }
Hoonki Lee27511902013-03-14 18:19:06 -070015894 }
15895
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015896 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15897 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015898 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015899 {
15900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015901 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015902 " TDLS setup is ongoing. action %d declined.",
15903 __func__, MAC_ADDR_ARRAY(peer), action_code);
15904 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015905 }
15906 }
15907
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015908 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15909 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015910 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015911 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15912 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015913 {
15914 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15915 we return error code at 'add_station()'. Hence we have this
15916 check again in addtion to add_station().
15917 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015918 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015919 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15921 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015922 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15923 __func__, MAC_ADDR_ARRAY(peer), action_code,
15924 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015925 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015926 }
15927 else
15928 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015929 /* maximum reached. tweak to send error code to peer and return
15930 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015931 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15933 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015934 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15935 __func__, MAC_ADDR_ARRAY(peer), status_code,
15936 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015937 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015938 /* fall through to send setup resp with failure status
15939 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015940 }
15941 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015942 else
15943 {
15944 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015945 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015946 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015947 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015949 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15950 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015951 return -EPERM;
15952 }
15953 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015954 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015955
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015957 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015958 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15959 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015960
Hoonki Leea34dd892013-02-05 22:56:02 -080015961 /*Except teardown responder will not be used so just make 0*/
15962 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015963 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015964 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015965
15966 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015968
15969 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15970 responder = pTdlsPeer->is_responder;
15971 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015972 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015974 "%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 -070015975 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15976 dialog_token, status_code, len);
15977 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015978 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015979 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015980
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015981 /* For explicit trigger of DIS_REQ come out of BMPS for
15982 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015983 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015984 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15985 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015986 {
15987 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15988 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015990 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015991 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15992 if (status != VOS_STATUS_SUCCESS) {
15993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15994 }
Hoonki Lee14621352013-04-16 17:51:19 -070015995 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015996 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015997 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15999 }
16000 }
Hoonki Lee14621352013-04-16 17:51:19 -070016001 }
16002
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016003 /* make sure doesn't call send_mgmt() while it is pending */
16004 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
16005 {
16006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016007 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016008 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016009 ret = -EBUSY;
16010 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016011 }
16012
16013 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016014 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
16015
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016016 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
16017 pAdapter->sessionId, peer, action_code, dialog_token,
16018 status_code, peer_capability, (tANI_U8 *)buf, len,
16019 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016020
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016021 if (VOS_STATUS_SUCCESS != status)
16022 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16024 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016025 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016026 ret = -EINVAL;
16027 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016028 }
16029
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016030 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
16031 (SIR_MAC_TDLS_DIS_RSP == action_code))
16032 {
16033 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
16034 * So we no need to wait for tdls_mgmt_comp for sending ack status.
16035 */
16036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16037 "%s: tx done for frm %u", __func__, action_code);
16038 return 0;
16039 }
16040
16041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16042 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
16043 WAIT_TIME_TDLS_MGMT);
16044
Hoonki Leed37cbb32013-04-20 00:31:14 -070016045 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
16046 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
16047
16048 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016049 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070016050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016051 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070016052 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016053 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080016054
16055 if (pHddCtx->isLogpInProgress)
16056 {
16057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16058 "%s: LOGP in Progress. Ignore!!!", __func__);
16059 return -EAGAIN;
16060 }
16061
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016062 ret = -EINVAL;
16063 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016064 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016065 else
16066 {
16067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16068 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
16069 __func__, rc, pAdapter->mgmtTxCompletionStatus);
16070 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016071
Gopichand Nakkala05922802013-03-14 12:23:19 -070016072 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070016073 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016074 ret = max_sta_failed;
16075 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070016076 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016077
Hoonki Leea34dd892013-02-05 22:56:02 -080016078 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
16079 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016080 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16082 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016083 }
16084 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
16085 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016086 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16088 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016089 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016090
16091 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016092
16093tx_failed:
16094 /* add_station will be called before sending TDLS_SETUP_REQ and
16095 * TDLS_SETUP_RSP and as part of add_station driver will enable
16096 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
16097 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
16098 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
16099 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
16100 */
16101
16102 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
16103 (SIR_MAC_TDLS_SETUP_RSP == action_code))
16104 wlan_hdd_tdls_check_bmps(pAdapter);
16105 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016106}
16107
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016108#if TDLS_MGMT_VERSION2
16109static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16110 u8 *peer, u8 action_code, u8 dialog_token,
16111 u16 status_code, u32 peer_capability,
16112 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016113#else /* TDLS_MGMT_VERSION2 */
16114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16115static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16116 struct net_device *dev,
16117 const u8 *peer, u8 action_code,
16118 u8 dialog_token, u16 status_code,
16119 u32 peer_capability, bool initiator,
16120 const u8 *buf, size_t len)
16121#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16122static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16123 struct net_device *dev,
16124 const u8 *peer, u8 action_code,
16125 u8 dialog_token, u16 status_code,
16126 u32 peer_capability, const u8 *buf,
16127 size_t len)
16128#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16129static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16130 struct net_device *dev,
16131 u8 *peer, u8 action_code,
16132 u8 dialog_token,
16133 u16 status_code, u32 peer_capability,
16134 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016135#else
16136static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16137 u8 *peer, u8 action_code, u8 dialog_token,
16138 u16 status_code, const u8 *buf, size_t len)
16139#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016140#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016141{
16142 int ret;
16143
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016144 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016145#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016146 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16147 dialog_token, status_code,
16148 peer_capability, buf, len);
16149#else /* TDLS_MGMT_VERSION2 */
16150#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16151 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16152 dialog_token, status_code,
16153 peer_capability, initiator,
16154 buf, len);
16155#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16156 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16157 dialog_token, status_code,
16158 peer_capability, buf, len);
16159#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16160 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16161 dialog_token, status_code,
16162 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016163#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016164 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16165 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016166#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016167#endif
16168 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016169
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016170 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016171}
Atul Mittal115287b2014-07-08 13:26:33 +053016172
16173int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16175 const u8 *peer,
16176#else
Atul Mittal115287b2014-07-08 13:26:33 +053016177 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016178#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016179 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016180 cfg80211_exttdls_callback callback)
16181{
16182
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016183 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16187 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16188 __func__, MAC_ADDR_ARRAY(peer));
16189
16190 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16191 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16192
16193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016194 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16195 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16196 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016197 return -ENOTSUPP;
16198 }
16199
16200 /* To cater the requirement of establishing the TDLS link
16201 * irrespective of the data traffic , get an entry of TDLS peer.
16202 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016203 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016204 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16205 if (pTdlsPeer == NULL) {
16206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16207 "%s: peer " MAC_ADDRESS_STR " not existing",
16208 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016209 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016210 return -EINVAL;
16211 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016212 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016213
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016214 /* check FW TDLS Off Channel capability */
16215 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016216 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016217 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016218 {
16219 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16220 pTdlsPeer->peerParams.global_operating_class =
16221 tdls_peer_params->global_operating_class;
16222 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16223 pTdlsPeer->peerParams.min_bandwidth_kbps =
16224 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016225 /* check configured channel is valid, non dfs and
16226 * not current operating channel */
16227 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16228 tdls_peer_params->channel)) &&
16229 (pHddStaCtx) &&
16230 (tdls_peer_params->channel !=
16231 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016232 {
16233 pTdlsPeer->isOffChannelConfigured = TRUE;
16234 }
16235 else
16236 {
16237 pTdlsPeer->isOffChannelConfigured = FALSE;
16238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16239 "%s: Configured Tdls Off Channel is not valid", __func__);
16240
16241 }
16242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016243 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16244 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016245 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016246 pTdlsPeer->isOffChannelConfigured,
16247 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016248 }
16249 else
16250 {
16251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016252 "%s: TDLS off channel FW capability %d, "
16253 "host capab %d or Invalid TDLS Peer Params", __func__,
16254 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16255 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016256 }
16257
Atul Mittal115287b2014-07-08 13:26:33 +053016258 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16259
16260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16261 " %s TDLS Add Force Peer Failed",
16262 __func__);
16263 return -EINVAL;
16264 }
16265 /*EXT TDLS*/
16266
16267 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16269 " %s TDLS set callback Failed",
16270 __func__);
16271 return -EINVAL;
16272 }
16273
16274 return(0);
16275
16276}
16277
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016278int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16279#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16280 const u8 *peer
16281#else
16282 u8 *peer
16283#endif
16284)
Atul Mittal115287b2014-07-08 13:26:33 +053016285{
16286
16287 hddTdlsPeer_t *pTdlsPeer;
16288 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16290 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16291 __func__, MAC_ADDR_ARRAY(peer));
16292
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016293 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16295 return -EINVAL;
16296 }
16297
Atul Mittal115287b2014-07-08 13:26:33 +053016298 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16299 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16300
16301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016302 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16303 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16304 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016305 return -ENOTSUPP;
16306 }
16307
16308
16309 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16310
16311 if ( NULL == pTdlsPeer ) {
16312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016313 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016314 __func__, MAC_ADDR_ARRAY(peer));
16315 return -EINVAL;
16316 }
16317 else {
16318 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16319 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016320 /* if channel switch is configured, reset
16321 the channel for this peer */
16322 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16323 {
16324 pTdlsPeer->peerParams.channel = 0;
16325 pTdlsPeer->isOffChannelConfigured = FALSE;
16326 }
Atul Mittal115287b2014-07-08 13:26:33 +053016327 }
16328
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016329 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016331 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016332 }
Atul Mittal115287b2014-07-08 13:26:33 +053016333
16334 /*EXT TDLS*/
16335
16336 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16337
16338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16339 " %s TDLS set callback Failed",
16340 __func__);
16341 return -EINVAL;
16342 }
16343 return(0);
16344
16345}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016346static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16348 const u8 *peer,
16349#else
16350 u8 *peer,
16351#endif
16352 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016353{
16354 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16355 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016356 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016357 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016358
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016359 ENTER();
16360
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016361 if (!pAdapter) {
16362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16363 return -EINVAL;
16364 }
16365
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16367 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16368 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016369 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016370 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016372 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016373 return -EINVAL;
16374 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016375
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016376 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016377 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016378 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016379 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016380 }
16381
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016382
16383 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016384 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016385 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016387 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16388 "Cannot process TDLS commands",
16389 pHddCtx->cfg_ini->fEnableTDLSSupport,
16390 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016391 return -ENOTSUPP;
16392 }
16393
16394 switch (oper) {
16395 case NL80211_TDLS_ENABLE_LINK:
16396 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016397 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016398 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016399 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016400 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016401 tANI_U16 numCurrTdlsPeers = 0;
16402 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016403 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016404
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16406 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16407 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016408 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016409 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016410 if ( NULL == pTdlsPeer ) {
16411 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16412 " (oper %d) not exsting. ignored",
16413 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16414 return -EINVAL;
16415 }
16416
16417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16418 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16419 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16420 "NL80211_TDLS_ENABLE_LINK");
16421
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016422 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16423 {
16424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16425 MAC_ADDRESS_STR " failed",
16426 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16427 return -EINVAL;
16428 }
16429
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016430 /* before starting tdls connection, set tdls
16431 * off channel established status to default value */
16432 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016433 /* TDLS Off Channel, Disable tdls channel switch,
16434 when there are more than one tdls link */
16435 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016436 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016437 {
16438 /* get connected peer and send disable tdls off chan */
16439 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016440 if ((connPeer) &&
16441 (connPeer->isOffChannelSupported == TRUE) &&
16442 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016443 {
16444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16445 "%s: More then one peer connected, Disable "
16446 "TDLS channel switch", __func__);
16447
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016448 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016449 ret = sme_SendTdlsChanSwitchReq(
16450 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016451 pAdapter->sessionId,
16452 connPeer->peerMac,
16453 connPeer->peerParams.channel,
16454 TDLS_OFF_CHANNEL_BW_OFFSET,
16455 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016456 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016457 hddLog(VOS_TRACE_LEVEL_ERROR,
16458 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016459 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016460 }
16461 else
16462 {
16463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16464 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016465 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016466 "isOffChannelConfigured %d",
16467 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016468 (connPeer ? (connPeer->isOffChannelSupported)
16469 : -1),
16470 (connPeer ? (connPeer->isOffChannelConfigured)
16471 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016472 }
16473 }
16474
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016475 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016476 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016477 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016478
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016479 if (0 != wlan_hdd_tdls_get_link_establish_params(
16480 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016482 return -EINVAL;
16483 }
16484 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016485
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016486 ret = sme_SendTdlsLinkEstablishParams(
16487 WLAN_HDD_GET_HAL_CTX(pAdapter),
16488 pAdapter->sessionId, peer,
16489 &tdlsLinkEstablishParams);
16490 if (ret != VOS_STATUS_SUCCESS) {
16491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16492 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016493 /* Send TDLS peer UAPSD capabilities to the firmware and
16494 * register with the TL on after the response for this operation
16495 * is received .
16496 */
16497 ret = wait_for_completion_interruptible_timeout(
16498 &pAdapter->tdls_link_establish_req_comp,
16499 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16500 if (ret <= 0)
16501 {
16502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016503 FL("Link Establish Request Failed Status %ld"),
16504 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016505 return -EINVAL;
16506 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016507 }
Atul Mittal115287b2014-07-08 13:26:33 +053016508 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16509 eTDLS_LINK_CONNECTED,
16510 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016511 staDesc.ucSTAId = pTdlsPeer->staId;
16512 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016513 ret = WLANTL_UpdateTdlsSTAClient(
16514 pHddCtx->pvosContext,
16515 &staDesc);
16516 if (ret != VOS_STATUS_SUCCESS) {
16517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16518 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016519
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016520 /* Mark TDLS client Authenticated .*/
16521 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16522 pTdlsPeer->staId,
16523 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016524 if (VOS_STATUS_SUCCESS == status)
16525 {
Hoonki Lee14621352013-04-16 17:51:19 -070016526 if (pTdlsPeer->is_responder == 0)
16527 {
16528 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016529 tdlsConnInfo_t *tdlsInfo;
16530
16531 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16532
16533 /* Initialize initiator wait callback */
16534 vos_timer_init(
16535 &pTdlsPeer->initiatorWaitTimeoutTimer,
16536 VOS_TIMER_TYPE_SW,
16537 wlan_hdd_tdls_initiator_wait_cb,
16538 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016539
16540 wlan_hdd_tdls_timer_restart(pAdapter,
16541 &pTdlsPeer->initiatorWaitTimeoutTimer,
16542 WAIT_TIME_TDLS_INITIATOR);
16543 /* suspend initiator TX until it receives direct packet from the
16544 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016545 ret = WLANTL_SuspendDataTx(
16546 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16547 &staId, NULL);
16548 if (ret != VOS_STATUS_SUCCESS) {
16549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16550 }
Hoonki Lee14621352013-04-16 17:51:19 -070016551 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016552
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016553 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016554 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016555 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016556 suppChannelLen =
16557 tdlsLinkEstablishParams.supportedChannelsLen;
16558
16559 if ((suppChannelLen > 0) &&
16560 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16561 {
16562 tANI_U8 suppPeerChannel = 0;
16563 int i = 0;
16564 for (i = 0U; i < suppChannelLen; i++)
16565 {
16566 suppPeerChannel =
16567 tdlsLinkEstablishParams.supportedChannels[i];
16568
16569 pTdlsPeer->isOffChannelSupported = FALSE;
16570 if (suppPeerChannel ==
16571 pTdlsPeer->peerParams.channel)
16572 {
16573 pTdlsPeer->isOffChannelSupported = TRUE;
16574 break;
16575 }
16576 }
16577 }
16578 else
16579 {
16580 pTdlsPeer->isOffChannelSupported = FALSE;
16581 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016582 }
16583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16584 "%s: TDLS channel switch request for channel "
16585 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016586 "%d isOffChannelSupported %d", __func__,
16587 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016588 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016589 suppChannelLen,
16590 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016591
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016592 /* TDLS Off Channel, Enable tdls channel switch,
16593 when their is only one tdls link and it supports */
16594 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16595 if ((numCurrTdlsPeers == 1) &&
16596 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16597 (TRUE == pTdlsPeer->isOffChannelConfigured))
16598 {
16599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16600 "%s: Send TDLS channel switch request for channel %d",
16601 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016602
16603 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016604 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16605 pAdapter->sessionId,
16606 pTdlsPeer->peerMac,
16607 pTdlsPeer->peerParams.channel,
16608 TDLS_OFF_CHANNEL_BW_OFFSET,
16609 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016610 if (ret != VOS_STATUS_SUCCESS) {
16611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16612 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016613 }
16614 else
16615 {
16616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16617 "%s: TDLS channel switch request not sent"
16618 " numCurrTdlsPeers %d "
16619 "isOffChannelSupported %d "
16620 "isOffChannelConfigured %d",
16621 __func__, numCurrTdlsPeers,
16622 pTdlsPeer->isOffChannelSupported,
16623 pTdlsPeer->isOffChannelConfigured);
16624 }
16625
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016626 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016627 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016628
16629 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016630 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16631 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016632 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016633 int ac;
16634 uint8 ucAc[4] = { WLANTL_AC_VO,
16635 WLANTL_AC_VI,
16636 WLANTL_AC_BK,
16637 WLANTL_AC_BE };
16638 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16639 for(ac=0; ac < 4; ac++)
16640 {
16641 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16642 pTdlsPeer->staId, ucAc[ac],
16643 tlTid[ac], tlTid[ac], 0, 0,
16644 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016645 if (status != VOS_STATUS_SUCCESS) {
16646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16647 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016648 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016649 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016650 }
16651
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016652 }
16653 break;
16654 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016655 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016656 tANI_U16 numCurrTdlsPeers = 0;
16657 hddTdlsPeer_t *connPeer = NULL;
16658
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16660 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16661 __func__, MAC_ADDR_ARRAY(peer));
16662
Sunil Dutt41de4e22013-11-14 18:09:02 +053016663 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16664
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016665
Sunil Dutt41de4e22013-11-14 18:09:02 +053016666 if ( NULL == pTdlsPeer ) {
16667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16668 " (oper %d) not exsting. ignored",
16669 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16670 return -EINVAL;
16671 }
16672
16673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16674 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16675 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16676 "NL80211_TDLS_DISABLE_LINK");
16677
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016678 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016679 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016680 long status;
16681
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016682 /* set tdls off channel status to false for this peer */
16683 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016684 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16685 eTDLS_LINK_TEARING,
16686 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16687 eTDLS_LINK_UNSPECIFIED:
16688 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016689 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16690
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016691 status = sme_DeleteTdlsPeerSta(
16692 WLAN_HDD_GET_HAL_CTX(pAdapter),
16693 pAdapter->sessionId, peer );
16694 if (status != VOS_STATUS_SUCCESS) {
16695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16696 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016697
16698 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16699 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016700 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016701 eTDLS_LINK_IDLE,
16702 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016703 if (status <= 0)
16704 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16706 "%s: Del station failed status %ld",
16707 __func__, status);
16708 return -EPERM;
16709 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016710
16711 /* TDLS Off Channel, Enable tdls channel switch,
16712 when their is only one tdls link and it supports */
16713 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16714 if (numCurrTdlsPeers == 1)
16715 {
16716 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16717 if ((connPeer) &&
16718 (connPeer->isOffChannelSupported == TRUE) &&
16719 (connPeer->isOffChannelConfigured == TRUE))
16720 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016721 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016722 status = sme_SendTdlsChanSwitchReq(
16723 WLAN_HDD_GET_HAL_CTX(pAdapter),
16724 pAdapter->sessionId,
16725 connPeer->peerMac,
16726 connPeer->peerParams.channel,
16727 TDLS_OFF_CHANNEL_BW_OFFSET,
16728 TDLS_CHANNEL_SWITCH_ENABLE);
16729 if (status != VOS_STATUS_SUCCESS) {
16730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16731 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016732 }
16733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16734 "%s: TDLS channel switch "
16735 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016736 "isOffChannelConfigured %d "
16737 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016738 __func__,
16739 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016740 (connPeer ? connPeer->isOffChannelConfigured : -1),
16741 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016742 }
16743 else
16744 {
16745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16746 "%s: TDLS channel switch request not sent "
16747 "numCurrTdlsPeers %d ",
16748 __func__, numCurrTdlsPeers);
16749 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016750 }
16751 else
16752 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16754 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016755 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016756 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016757 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016758 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016759 {
Atul Mittal115287b2014-07-08 13:26:33 +053016760 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016761
Atul Mittal115287b2014-07-08 13:26:33 +053016762 if (0 != status)
16763 {
16764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016765 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016766 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016767 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016768 break;
16769 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016770 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016771 {
Atul Mittal115287b2014-07-08 13:26:33 +053016772 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16773 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016774 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016775 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016776
Atul Mittal115287b2014-07-08 13:26:33 +053016777 if (0 != status)
16778 {
16779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016780 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016781 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016782 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016783 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016784 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016785 case NL80211_TDLS_DISCOVERY_REQ:
16786 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016788 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016789 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016790 return -ENOTSUPP;
16791 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16793 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016794 return -ENOTSUPP;
16795 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016796
16797 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016798 return 0;
16799}
Chilam NG571c65a2013-01-19 12:27:36 +053016800
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016801static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016802#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16803 const u8 *peer,
16804#else
16805 u8 *peer,
16806#endif
16807 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016808{
16809 int ret;
16810
16811 vos_ssr_protect(__func__);
16812 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16813 vos_ssr_unprotect(__func__);
16814
16815 return ret;
16816}
16817
Chilam NG571c65a2013-01-19 12:27:36 +053016818int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16819 struct net_device *dev, u8 *peer)
16820{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016821 hddLog(VOS_TRACE_LEVEL_INFO,
16822 "tdls send discover req: "MAC_ADDRESS_STR,
16823 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016824
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016825#if TDLS_MGMT_VERSION2
16826 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16827 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16828#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016829#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16830 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16831 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16832#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16833 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16834 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16835#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16836 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16837 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16838#else
Chilam NG571c65a2013-01-19 12:27:36 +053016839 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16840 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016841#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016842#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016843}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016844#endif
16845
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016846#ifdef WLAN_FEATURE_GTK_OFFLOAD
16847/*
16848 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16849 * Callback rountine called upon receiving response for
16850 * get offload info
16851 */
16852void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16853 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16854{
16855
16856 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016857 tANI_U8 tempReplayCounter[8];
16858 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016859
16860 ENTER();
16861
16862 if (NULL == pAdapter)
16863 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016865 "%s: HDD adapter is Null", __func__);
16866 return ;
16867 }
16868
16869 if (NULL == pGtkOffloadGetInfoRsp)
16870 {
16871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16872 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16873 return ;
16874 }
16875
16876 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16877 {
16878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16879 "%s: wlan Failed to get replay counter value",
16880 __func__);
16881 return ;
16882 }
16883
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16885 /* Update replay counter */
16886 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16887 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16888
16889 {
16890 /* changing from little to big endian since supplicant
16891 * works on big endian format
16892 */
16893 int i;
16894 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16895
16896 for (i = 0; i < 8; i++)
16897 {
16898 tempReplayCounter[7-i] = (tANI_U8)p[i];
16899 }
16900 }
16901
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016902 /* Update replay counter to NL */
16903 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016904 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016905}
16906
16907/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016908 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016909 * This function is used to offload GTK rekeying job to the firmware.
16910 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016911int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016912 struct cfg80211_gtk_rekey_data *data)
16913{
16914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16916 hdd_station_ctx_t *pHddStaCtx;
16917 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016918 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016919 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016920 eHalStatus status = eHAL_STATUS_FAILURE;
16921
16922 ENTER();
16923
16924 if (NULL == pAdapter)
16925 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016927 "%s: HDD adapter is Null", __func__);
16928 return -ENODEV;
16929 }
16930
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16932 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16933 pAdapter->sessionId, pAdapter->device_mode));
16934
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016935 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016936 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016937 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016938 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016939 }
16940
16941 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16942 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16943 if (NULL == hHal)
16944 {
16945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16946 "%s: HAL context is Null!!!", __func__);
16947 return -EAGAIN;
16948 }
16949
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016950 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16951 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16952 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16953 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016954 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016955 {
16956 /* changing from big to little endian since driver
16957 * works on little endian format
16958 */
16959 tANI_U8 *p =
16960 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16961 int i;
16962
16963 for (i = 0; i < 8; i++)
16964 {
16965 p[7-i] = data->replay_ctr[i];
16966 }
16967 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016968
16969 if (TRUE == pHddCtx->hdd_wlan_suspended)
16970 {
16971 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016972 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16973 sizeof (tSirGtkOffloadParams));
16974 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016975 pAdapter->sessionId);
16976
16977 if (eHAL_STATUS_SUCCESS != status)
16978 {
16979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16980 "%s: sme_SetGTKOffload failed, returned %d",
16981 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016982
16983 /* Need to clear any trace of key value in the memory.
16984 * Thus zero out the memory even though it is local
16985 * variable.
16986 */
16987 vos_mem_zero(&hddGtkOffloadReqParams,
16988 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016989 return status;
16990 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16992 "%s: sme_SetGTKOffload successfull", __func__);
16993 }
16994 else
16995 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16997 "%s: wlan not suspended GTKOffload request is stored",
16998 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016999 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017000
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017001 /* Need to clear any trace of key value in the memory.
17002 * Thus zero out the memory even though it is local
17003 * variable.
17004 */
17005 vos_mem_zero(&hddGtkOffloadReqParams,
17006 sizeof(hddGtkOffloadReqParams));
17007
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017008 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017009 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017010}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017011
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017012int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
17013 struct cfg80211_gtk_rekey_data *data)
17014{
17015 int ret;
17016
17017 vos_ssr_protect(__func__);
17018 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
17019 vos_ssr_unprotect(__func__);
17020
17021 return ret;
17022}
17023#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017024/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017025 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017026 * This function is used to set access control policy
17027 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017028static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17029 struct net_device *dev,
17030 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017031{
17032 int i;
17033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17034 hdd_hostapd_state_t *pHostapdState;
17035 tsap_Config_t *pConfig;
17036 v_CONTEXT_t pVosContext = NULL;
17037 hdd_context_t *pHddCtx;
17038 int status;
17039
17040 ENTER();
17041
17042 if (NULL == pAdapter)
17043 {
17044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17045 "%s: HDD adapter is Null", __func__);
17046 return -ENODEV;
17047 }
17048
17049 if (NULL == params)
17050 {
17051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17052 "%s: params is Null", __func__);
17053 return -EINVAL;
17054 }
17055
17056 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17057 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017058 if (0 != status)
17059 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017060 return status;
17061 }
17062
17063 pVosContext = pHddCtx->pvosContext;
17064 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
17065
17066 if (NULL == pHostapdState)
17067 {
17068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17069 "%s: pHostapdState is Null", __func__);
17070 return -EINVAL;
17071 }
17072
17073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
17074 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17076 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
17077 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017078
17079 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
17080 {
17081 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
17082
17083 /* default value */
17084 pConfig->num_accept_mac = 0;
17085 pConfig->num_deny_mac = 0;
17086
17087 /**
17088 * access control policy
17089 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
17090 * listed in hostapd.deny file.
17091 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
17092 * listed in hostapd.accept file.
17093 */
17094 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
17095 {
17096 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
17097 }
17098 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
17099 {
17100 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
17101 }
17102 else
17103 {
17104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17105 "%s:Acl Policy : %d is not supported",
17106 __func__, params->acl_policy);
17107 return -ENOTSUPP;
17108 }
17109
17110 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
17111 {
17112 pConfig->num_accept_mac = params->n_acl_entries;
17113 for (i = 0; i < params->n_acl_entries; i++)
17114 {
17115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17116 "** Add ACL MAC entry %i in WhiletList :"
17117 MAC_ADDRESS_STR, i,
17118 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17119
17120 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17121 sizeof(qcmacaddr));
17122 }
17123 }
17124 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17125 {
17126 pConfig->num_deny_mac = params->n_acl_entries;
17127 for (i = 0; i < params->n_acl_entries; i++)
17128 {
17129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17130 "** Add ACL MAC entry %i in BlackList :"
17131 MAC_ADDRESS_STR, i,
17132 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17133
17134 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17135 sizeof(qcmacaddr));
17136 }
17137 }
17138
17139 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17140 {
17141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17142 "%s: SAP Set Mac Acl fail", __func__);
17143 return -EINVAL;
17144 }
17145 }
17146 else
17147 {
17148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017149 "%s: Invalid device_mode = %s (%d)",
17150 __func__, hdd_device_modetoString(pAdapter->device_mode),
17151 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017152 return -EINVAL;
17153 }
17154
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017155 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017156 return 0;
17157}
17158
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017159static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17160 struct net_device *dev,
17161 const struct cfg80211_acl_data *params)
17162{
17163 int ret;
17164 vos_ssr_protect(__func__);
17165 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17166 vos_ssr_unprotect(__func__);
17167
17168 return ret;
17169}
17170
Leo Chang9056f462013-08-01 19:21:11 -070017171#ifdef WLAN_NL80211_TESTMODE
17172#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017173void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017174(
17175 void *pAdapter,
17176 void *indCont
17177)
17178{
Leo Changd9df8aa2013-09-26 13:32:26 -070017179 tSirLPHBInd *lphbInd;
17180 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017181 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017182
17183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017184 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017185
c_hpothu73f35e62014-04-18 13:40:08 +053017186 if (pAdapter == NULL)
17187 {
17188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17189 "%s: pAdapter is NULL\n",__func__);
17190 return;
17191 }
17192
Leo Chang9056f462013-08-01 19:21:11 -070017193 if (NULL == indCont)
17194 {
17195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017196 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017197 return;
17198 }
17199
c_hpothu73f35e62014-04-18 13:40:08 +053017200 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017201 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017202 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017203 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017204 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017205 GFP_ATOMIC);
17206 if (!skb)
17207 {
17208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17209 "LPHB timeout, NL buffer alloc fail");
17210 return;
17211 }
17212
Leo Changac3ba772013-10-07 09:47:04 -070017213 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017214 {
17215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17216 "WLAN_HDD_TM_ATTR_CMD put fail");
17217 goto nla_put_failure;
17218 }
Leo Changac3ba772013-10-07 09:47:04 -070017219 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017220 {
17221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17222 "WLAN_HDD_TM_ATTR_TYPE put fail");
17223 goto nla_put_failure;
17224 }
Leo Changac3ba772013-10-07 09:47:04 -070017225 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017226 sizeof(tSirLPHBInd), lphbInd))
17227 {
17228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17229 "WLAN_HDD_TM_ATTR_DATA put fail");
17230 goto nla_put_failure;
17231 }
Leo Chang9056f462013-08-01 19:21:11 -070017232 cfg80211_testmode_event(skb, GFP_ATOMIC);
17233 return;
17234
17235nla_put_failure:
17236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17237 "NLA Put fail");
17238 kfree_skb(skb);
17239
17240 return;
17241}
17242#endif /* FEATURE_WLAN_LPHB */
17243
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017244static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017245{
17246 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17247 int err = 0;
17248#ifdef FEATURE_WLAN_LPHB
17249 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017250 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017251
17252 ENTER();
17253
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017254 err = wlan_hdd_validate_context(pHddCtx);
17255 if (0 != err)
17256 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017257 return err;
17258 }
Leo Chang9056f462013-08-01 19:21:11 -070017259#endif /* FEATURE_WLAN_LPHB */
17260
17261 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17262 if (err)
17263 {
17264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17265 "%s Testmode INV ATTR", __func__);
17266 return err;
17267 }
17268
17269 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17270 {
17271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17272 "%s Testmode INV CMD", __func__);
17273 return -EINVAL;
17274 }
17275
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017276 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17277 TRACE_CODE_HDD_CFG80211_TESTMODE,
17278 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017279 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17280 {
17281#ifdef FEATURE_WLAN_LPHB
17282 /* Low Power Heartbeat configuration request */
17283 case WLAN_HDD_TM_CMD_WLAN_HB:
17284 {
17285 int buf_len;
17286 void *buf;
17287 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017288 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017289
17290 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17291 {
17292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17293 "%s Testmode INV DATA", __func__);
17294 return -EINVAL;
17295 }
17296
17297 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17298 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017299
17300 hb_params_temp =(tSirLPHBReq *)buf;
17301 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17302 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17303 return -EINVAL;
17304
Leo Chang9056f462013-08-01 19:21:11 -070017305 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17306 if (NULL == hb_params)
17307 {
17308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17309 "%s Request Buffer Alloc Fail", __func__);
17310 return -EINVAL;
17311 }
17312
17313 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017314 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17315 hb_params,
17316 wlan_hdd_cfg80211_lphb_ind_handler);
17317 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017318 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17320 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017321 vos_mem_free(hb_params);
17322 }
Leo Chang9056f462013-08-01 19:21:11 -070017323 return 0;
17324 }
17325#endif /* FEATURE_WLAN_LPHB */
17326 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17328 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017329 return -EOPNOTSUPP;
17330 }
17331
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017332 EXIT();
17333 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017334}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017335
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017336static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17337#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17338 struct wireless_dev *wdev,
17339#endif
17340 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017341{
17342 int ret;
17343
17344 vos_ssr_protect(__func__);
17345 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17346 vos_ssr_unprotect(__func__);
17347
17348 return ret;
17349}
Leo Chang9056f462013-08-01 19:21:11 -070017350#endif /* CONFIG_NL80211_TESTMODE */
17351
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017352static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017353 struct net_device *dev,
17354 int idx, struct survey_info *survey)
17355{
17356 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17357 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017358 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017359 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017360 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017361 v_S7_t snr,rssi;
17362 int status, i, j, filled = 0;
17363
17364 ENTER();
17365
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017366 if (NULL == pAdapter)
17367 {
17368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17369 "%s: HDD adapter is Null", __func__);
17370 return -ENODEV;
17371 }
17372
17373 if (NULL == wiphy)
17374 {
17375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17376 "%s: wiphy is Null", __func__);
17377 return -ENODEV;
17378 }
17379
17380 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17381 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017382 if (0 != status)
17383 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017384 return status;
17385 }
17386
Mihir Sheted9072e02013-08-21 17:02:29 +053017387 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17388
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017389 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017390 0 != pAdapter->survey_idx ||
17391 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017392 {
17393 /* The survey dump ops when implemented completely is expected to
17394 * return a survey of all channels and the ops is called by the
17395 * kernel with incremental values of the argument 'idx' till it
17396 * returns -ENONET. But we can only support the survey for the
17397 * operating channel for now. survey_idx is used to track
17398 * that the ops is called only once and then return -ENONET for
17399 * the next iteration
17400 */
17401 pAdapter->survey_idx = 0;
17402 return -ENONET;
17403 }
17404
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017405 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17406 {
17407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17408 "%s: Roaming in progress, hence return ", __func__);
17409 return -ENONET;
17410 }
17411
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017412 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17413
17414 wlan_hdd_get_snr(pAdapter, &snr);
17415 wlan_hdd_get_rssi(pAdapter, &rssi);
17416
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17418 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17419 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017420 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17421 hdd_wlan_get_freq(channel, &freq);
17422
17423
17424 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17425 {
17426 if (NULL == wiphy->bands[i])
17427 {
17428 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17429 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17430 continue;
17431 }
17432
17433 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17434 {
17435 struct ieee80211_supported_band *band = wiphy->bands[i];
17436
17437 if (band->channels[j].center_freq == (v_U16_t)freq)
17438 {
17439 survey->channel = &band->channels[j];
17440 /* The Rx BDs contain SNR values in dB for the received frames
17441 * while the supplicant expects noise. So we calculate and
17442 * return the value of noise (dBm)
17443 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17444 */
17445 survey->noise = rssi - snr;
17446 survey->filled = SURVEY_INFO_NOISE_DBM;
17447 filled = 1;
17448 }
17449 }
17450 }
17451
17452 if (filled)
17453 pAdapter->survey_idx = 1;
17454 else
17455 {
17456 pAdapter->survey_idx = 0;
17457 return -ENONET;
17458 }
17459
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017460 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017461 return 0;
17462}
17463
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017464static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17465 struct net_device *dev,
17466 int idx, struct survey_info *survey)
17467{
17468 int ret;
17469
17470 vos_ssr_protect(__func__);
17471 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17472 vos_ssr_unprotect(__func__);
17473
17474 return ret;
17475}
17476
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017477/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017478 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017479 * this is called when cfg80211 driver resume
17480 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17481 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017482int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017483{
17484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17485 hdd_adapter_t *pAdapter;
17486 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17487 VOS_STATUS status = VOS_STATUS_SUCCESS;
17488
17489 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017490
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017491 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017492 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017493 return 0;
17494 }
17495
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017496 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17497 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017498 spin_lock(&pHddCtx->schedScan_lock);
17499 pHddCtx->isWiphySuspended = FALSE;
17500 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17501 {
17502 spin_unlock(&pHddCtx->schedScan_lock);
17503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17504 "%s: Return resume is not due to PNO indication", __func__);
17505 return 0;
17506 }
17507 // Reset flag to avoid updatating cfg80211 data old results again
17508 pHddCtx->isSchedScanUpdatePending = FALSE;
17509 spin_unlock(&pHddCtx->schedScan_lock);
17510
17511 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17512
17513 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17514 {
17515 pAdapter = pAdapterNode->pAdapter;
17516 if ( (NULL != pAdapter) &&
17517 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17518 {
17519 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017520 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17522 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017523 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017524 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017525 {
17526 /* Acquire wakelock to handle the case where APP's tries to
17527 * suspend immediately after updating the scan results. Whis
17528 * results in app's is in suspended state and not able to
17529 * process the connect request to AP
17530 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017531 hdd_prevent_suspend_timeout(2000,
17532 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017533 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017534 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017535
17536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17537 "%s : cfg80211 scan result database updated", __func__);
17538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017539 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017540 return 0;
17541
17542 }
17543 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17544 pAdapterNode = pNext;
17545 }
17546
17547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17548 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017549 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017550 return 0;
17551}
17552
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017553int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17554{
17555 int ret;
17556
17557 vos_ssr_protect(__func__);
17558 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17559 vos_ssr_unprotect(__func__);
17560
17561 return ret;
17562}
17563
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017564/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017565 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017566 * this is called when cfg80211 driver suspends
17567 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017568int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017569 struct cfg80211_wowlan *wow)
17570{
17571 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017572 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017573
17574 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017575
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017576 ret = wlan_hdd_validate_context(pHddCtx);
17577 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017578 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017579 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017580 }
17581
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017582
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017583 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17584 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17585 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017586 pHddCtx->isWiphySuspended = TRUE;
17587
17588 EXIT();
17589
17590 return 0;
17591}
17592
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017593int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17594 struct cfg80211_wowlan *wow)
17595{
17596 int ret;
17597
17598 vos_ssr_protect(__func__);
17599 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17600 vos_ssr_unprotect(__func__);
17601
17602 return ret;
17603}
Jeff Johnson295189b2012-06-20 16:38:30 -070017604/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017605static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017606{
17607 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17608 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17609 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17610 .change_station = wlan_hdd_change_station,
17611#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17612 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17613 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17614 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017615#else
17616 .start_ap = wlan_hdd_cfg80211_start_ap,
17617 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17618 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017619#endif
17620 .change_bss = wlan_hdd_cfg80211_change_bss,
17621 .add_key = wlan_hdd_cfg80211_add_key,
17622 .get_key = wlan_hdd_cfg80211_get_key,
17623 .del_key = wlan_hdd_cfg80211_del_key,
17624 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017625#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017626 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017627#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017628 .scan = wlan_hdd_cfg80211_scan,
17629 .connect = wlan_hdd_cfg80211_connect,
17630 .disconnect = wlan_hdd_cfg80211_disconnect,
17631 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17632 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17633 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17634 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17635 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017636 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17637 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017638 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017639#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17640 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17641 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17642 .set_txq_params = wlan_hdd_set_txq_params,
17643#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017644 .get_station = wlan_hdd_cfg80211_get_station,
17645 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17646 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017647 .add_station = wlan_hdd_cfg80211_add_station,
17648#ifdef FEATURE_WLAN_LFR
17649 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17650 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17651 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17652#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017653#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17654 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17655#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017656#ifdef FEATURE_WLAN_TDLS
17657 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17658 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17659#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017660#ifdef WLAN_FEATURE_GTK_OFFLOAD
17661 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17662#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017663#ifdef FEATURE_WLAN_SCAN_PNO
17664 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17665 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17666#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017667 .resume = wlan_hdd_cfg80211_resume_wlan,
17668 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017669 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017670#ifdef WLAN_NL80211_TESTMODE
17671 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17672#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017673 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017674};
17675